﻿// Проблеми:
//!+ PrintLastMove() реже в началото от първия символ на първия ход на човек в режим срещу компютър
//! 151 belite pi6at vyrhu dyskata i ne se iztriva pri sgre6en hod
//!++ 1 -> 1 + x Enter прави changeGameModeBy = -1
//!++ =? kazwa gre6no, kakto i vij koga da se smenq player v ending
//!++ 
//! Режим CheckMoveList :
//!++ Довърши края на 'Validate anonce AFTER move figure(s)'
//!++   .   free : + :+ # :#   = := += :+= urong
//?+  .   free : + :+ # :#   
//!++ Exeptions
//! Провери с нарочно грешни ходове в режим на четене от лист:
//!++ urongMove
//!++ unwantedMove
//!++ unwantedMoves
//!++ unfinishedList
//!++ 

// Подозрения:
//?++ 

// Забележки:
//? извън тестов режим, да закоментирвам трудността в StartingInitialisation()
//?+ в AvoidMateInOne(), ако искаме да търсим точно какво имаме и за специалните Ремита, трябва да запазваме към SaveBattlefields[] и maxMatches и виртуалния ход и чак тогава да се проверява, (ТОВА ОТПАДА: а отделно предварително да се провери дори Random дали го позволява за директен Пат още преди ход)

// Липсват:
//!++ =? може да се поиска по всяко време, а ако е преди ход, опонента може да поиска първо да се направи хода и тогава да отговори дали е съгласен
//!++ 
//!++ random в съответните интервали навсякъде ... за Реми, ако се появи различна възможност след местене на фигура
//!++ 
//!++ нов мод, в който след края на играта може да се разхождаме из ходовете
//!++ нов мод за генериране на партия и намиране на шах/изход от шах/мат/пат в избираем брой ходове
//!++ 

// Оптимизации:
//? редуцирай FullPrint() (at draw, resign, ...) за увеличаване на скоростта
//? 

// Клавишни комбинации:
//? Ctrl+M+Ctrl+O (свива) && Ctrl+M+Ctrl+L (разгъва всички региони)
//? 

using System;
using System.IO;
using System.Text;
using System.Media;
using System.Security;
using System.Threading;
using System.Speech.Synthesis;
using System.Collections.Generic;

public class Chessmaster
{
    #region Variables

    public static int finishGameFromMove = -1; //! Започваме веднага след изиграването на finishGameFromMove-ия ход

    public static bool finishMoveInMoveList = false;

        #region Notation

    public enum Notation { LongAlgebraic, ShortAlgebraic, RandomAlgebraic };
    public static List<string> changeNotations = new List<string>() { "<", ">" };

    public static Notation computerNotation = Notation.RandomAlgebraic;
    public static Notation computerNotationCurrent;

    public static Notation playerNotation;
    public static Notation playersNotation;
    public static Notation whitePlayerNotation;
    public static Notation blackPlayerNotation;

        #endregion

        #region Последни

    public static bool shortAlgebraic;
    public static bool longAlgebraic;
    public static char symbolInMove;
    public static int symbolNumberInMove;
    public static int rowsInMove;
    public static int columnsInMove;
    public static int movesInMove;
    public static int takesInMove;
    public static int enPassantInMove;
    //public static string generalMove;
    //public static string generalMoveWithExchange;
    public static int shortAlgebraicRow;
    public static int shortAlgebraicColumn;
    public static int shortAlgebraicHowManyFiguresCanJump;
    public static int shortAlgebraicBeginFromSecondFigure;

    public static int totalSpeed;

    public static int leadingNumberOfMoveIntoList;

    public static string urong = "urong";

    public static bool emptyRawMoveList = false;
    public static bool emptyInappropriateMoveListArray = false;
    public static bool emptyMoveList = false;

    public static string urongMoveExample = "#####";
    public static bool urongMove = false;
    public static string urongMoveNote = "Urong Move!";
    public static bool unwantedMove = false;
    public static string unwantedMoveNote = "Unwanted Move!";
    public static bool unwantedMoves = false;
    public static string unwantedMovesNote = "Unwanted Moves!";
    public static bool unfinishedList = false;
    public static string unfinishedListNote = "Unwanted Move!";

    public static int enPassantPreparing = -9;

    public static bool enPassant = false;

    public static int drawQuestionOnMove = -3;
    public static int drawQuestionMoveInterval = 3; //! в тази бройка влиза и текущия ход, на който е бил отказан пат

    public static bool checkAndDraw = false;

        #endregion

        #region Additional intellect

    public enum Difficulty { Amateur = 0, Human = 1, Nightmare = 2 };
    public static List<string> gameDifficulties = new List<string>() { "A", "H", "N" };

    public static Difficulty gameDifficulty = Difficulty.Amateur;
    public static List<string> changeDifficulty = new List<string>() { "a", "h", "n", "4", "5", "6", "7", "8", "9" };

    public static Difficulty[] gameBothDifficulty = new Difficulty[] { Difficulty.Amateur, Difficulty.Amateur };

    public static bool mateInOne = false; // useless
    public static int mateInOneWithFigure = 0; // useless
    public static int mateInOneWithFigureOnMovement = 0; // useless

    public static bool drawInOne = false; // useless
    public static int drawInOneWithFigure = 0; // useless
    public static int drawInOneWithFigureOnMovement = 0; // useless

    //public static List<int> withEx = new List<int>() { 0, 0 };

    public static int maxGoodMoveOfAllFigures = 0;
    public static int maxGoodMoveOfCurrentFigure = 0;
    public static int maxGoodMoveOfCurrentFigureIndex = 0;

    public static int maxRepetition = 0; // useless
    public static string currentBattlefield = "";
    public static int maxRepetitionWithCurrentBattlefield = 0;

    public static int crossMovesOfCurrentFigure;
    public static int crossFigures;

    public static int countToRightIndex;
    public static int countToRightPerfectFigure;

    public static int perfectFigure = 0;
    public static int perfectFigureIndex = 0;
    public static int perfectMovementIndexOfPerfectFigure = 0;

    public static int howManyPerfectFigures = 0;
    public static int howManyPerfectMovesOfThisPerfectFigure = 0;

    public static int randomIndexOfPerfectFigure;
    public static int randomOnePerfectMoveOfThisPerfectFigure;
    public static int saveRandomIndexOfPerfectFigure;
    public static int saveRandomOnePerfectMoveOfThisPerfectFigure;

        #endregion

        #region Battlefield

    public static int[,] battlefield = new int[8, 8];
    public static List<List<List<int>>> figures = new List<List<List<int>>>();
    public static List<int> materials = new List<int>();
    public static List<List<string>> lastMoves = new List<List<string>>();

        #endregion

        #region Console

        #region Size

    public static int consoleWidth = 155; // it was 153
    public static int consoleHeight = 32;

        #endregion

        #region Colors

    public static ConsoleColor colorOfDefaultBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfDefaultForeground = ConsoleColor.White;

    public static ConsoleColor colorOfOuterFrameBackground = ConsoleColor.DarkGray;
    public static ConsoleColor colorOfOuterFrameForeground = ConsoleColor.White;

    public static ConsoleColor colorOfInternalFrame = ConsoleColor.Black;

    public static ConsoleColor colorOfWhiteFields = ConsoleColor.DarkGray;
    public static ConsoleColor colorOfBlackFields = ConsoleColor.Black;

    public static ConsoleColor colorOfWhiteFigures = ConsoleColor.White;
    public static ConsoleColor colorOfBlackFigures = ConsoleColor.Red;

    public static ConsoleColor colorOfNumbersOfMovesBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfNumbersOfMovesForeground = ConsoleColor.Blue;
    public static ConsoleColor colorOfNewNumberOfMovesBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfNewNumberOfMovesForeground = ConsoleColor.Cyan;
    public static ConsoleColor colorOfFirstMoveBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfFirstMoveForeground = ConsoleColor.Yellow;

    public static ConsoleColor colorOfMovesBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfMovesForeground = ConsoleColor.White;

    public static ConsoleColor colorOfTakensWhiteFigureBackground = ConsoleColor.DarkGray;
    public static ConsoleColor colorOfTakensWhiteFigureForeground = ConsoleColor.White;
    public static ConsoleColor colorOfTakensBlackFigureBackground = ConsoleColor.DarkGray;
    public static ConsoleColor colorOfTakensBlackFigureForeground = ConsoleColor.Red;

    public static ConsoleColor colorOfTheEndingDrawMoveBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTheEndingDrawMoveForeground = ConsoleColor.Green;
    public static ConsoleColor colorOfTheEndingCheckmateMoveBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTheEndingCheckmateMoveForeground = ConsoleColor.Red;
    public static ConsoleColor colorOfTheEndingResignMoveBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTheEndingResignMoveForeground = ConsoleColor.Magenta;

    public static ConsoleColor colorOfTopHelpBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTopHelpForeground = ConsoleColor.Yellow;
    public static ConsoleColor colorOfBottomHelpBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfBottomHelpForeground = ConsoleColor.Yellow;

    public static ConsoleColor colorOfGameModeBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfGameModeForeground = ConsoleColor.White;

    public static ConsoleColor colorOfSetsBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfSetsForeground = ConsoleColor.Cyan;

    public static ConsoleColor colorOfGameDifficultyBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfGameDifficultyForeground = ConsoleColor.DarkGreen;

    public static ConsoleColor colorOfTimersBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTimersForeground = ConsoleColor.Cyan;

    public static ConsoleColor colorOfTotalSpeedBackground = ConsoleColor.Black;
    public static ConsoleColor colorOfTotalSpeedForeground = ConsoleColor.DarkCyan;

    public static ConsoleColor colorOfGameModeChoiseAfterEndingBackground = ConsoleColor.Red;
    public static ConsoleColor colorOfGameModeChoiseAfterEndingForeground = ConsoleColor.White;

    public static ConsoleColor colorOfFinishGameFromMoveBackground = ConsoleColor.DarkGreen;
    public static ConsoleColor colorOfFinishGameFromMoveForeground = ConsoleColor.White;

    public static ConsoleColor colorOfChoiseGameModeToFinishGameFromMoveBackground = ConsoleColor.Magenta;
    public static ConsoleColor colorOfChoiseGameModeToFinishGameFromMoveForeground = ConsoleColor.White;

        #endregion

        #endregion

        #region Counters

            #region Reserve

    public static int i;
    public static int j;
    public static int k;

            #endregion

            #region Initials

    public static int ro;
    public static int col;

    public static int counterOfWhitePawn;
    public static int rowOfWhiteSpecialFigure;
    public static int rowOfWhitePawn;
    public static int columnOfWhitePawn;
    public static int counterOfBlackPawn;
    public static int rowOfBlackSpecialFigure;
    public static int rowOfBlackPawn;
    public static int columnOfBlackPawn;

    public static int ifml;

    public static int igd;

            #endregion

            #region Move players'

    public static int mprmosao;
    
    public static int mprmccq;

    public static int mpilmk;

    public static int mpscbi;
    public static int mpscbj;
    public static int mpscbk;

    public static int rif;

            #endregion

            #region Jump

    public static int jri;
    public static int jrj;

    public static int jbi;

            #endregion

            #region Print

    public static int pbi;
    public static int pbj;
    public static int pbk;

    public static int nextWhiteToMove;
    public static int plm;
    public static int mov;
    public static int colon;

    public static int pcmb;

    public static int plmbl;

            #endregion

            #region Figures players'

    public static int firstOfExchangeKind;

    public static int fpm;

    public static int fpr;

    public static int fpa;

    public static int fpri;

    public static int fprv;

            #endregion

            #region Artificial Intelligence

    public static int aifapmr;

    public static int aifapm;

    public static int aicfmioi;
    public static int aicfmioj;

    public static int aicfmioscbi;
    public static int aicfmioscbj;
    public static int aicfmioscbk;

    public static int aicfmioapm;
    public static int aicfmioriopf;
    public static int aicfmioropmotpf;

    public static int aiaacf; // Artificial Intelligence : Add All Candidates Figures
    public static int aiaacm; // Artificial Intelligence : Add All Candidates Moves

    public static int aicpmhmfcj;

            #endregion

            #region My errors

    public static int me;

            #endregion

        #endregion

        #region Draws

    //public enum Draws { Agreement = 0, FiftyMove = 1, Repetition = 2, Material = 3, Stalemate = 4, Time = 5 };
    //public static string giveDraw;

    public static string draw = "=";

    public static string question = "?";
    public static string answer = "=";
    public static string refuse = "-";

    public static string agreement = "Agreement";
    public static string fiftyMoveRule = "fifty-moveR";
    public static string repetition = "Repetition";
    public static string insufficientMaterial = "Material";
    public static string stalemate = "Stalemate";
    public static string bothFlagsDown = "Time";

    public static string drawQuestion = draw + question;
    public static string drawAnswer = answer;
    public static string drawAnswerRefuse = refuse;
    public static string drawByAgreementShort = draw + question + answer;
    public static string drawByAgreement = draw + question + answer + "Agreement";
    public static string drawByWhiteFiftyMoveRule = draw + "W" + fiftyMoveRule;
    public static string drawByBlackFiftyMoveRule = draw + "B" + fiftyMoveRule;
    public static string drawByRepetition = draw + repetition;
    public static string drawByInsufficientMaterial = draw + insufficientMaterial;
    public static string drawByStalemate = draw + stalemate;
    public static string drawByBothFlagsDown = draw + bothFlagsDown;

    public static string drawKind = "";

    public static StringBuilder saveCurrentBattlefield = new StringBuilder();
    public static List<string> saveBattlefields = new List<string>();
    public static List<int> matches = new List<int>();
    public static int maxMatches = 0;
    public static int maxMatchesEventually = 0;
    public static int indexOfCurrentBattlefield;
    public static List<int> passiveMoves = new List<int>() { 0, 0 };

        #endregion

        #region Figure's Units

    public const int emptyField = 0;

    public const int whiteDecimals = 10;
    public const int blackDecimals = 30;

    public const int kingUnits = 6;
    public const int queenUnits = 5;
    public const int rookUnits = 4;
    public const int bishopUnits = 3;
    public const int nightUnits = 2;
    public const int pawnUnits = 1;

    public const int whiteKing = whiteDecimals + kingUnits;
    public const int whiteQueen = whiteDecimals + queenUnits;
    public const int whiteRook = whiteDecimals + rookUnits;
    public const int whiteBishop = whiteDecimals + bishopUnits;
    public const int whiteNight = whiteDecimals + nightUnits;
    public const int whitePawn = whiteDecimals + pawnUnits;

    public const int blackKing = blackDecimals + kingUnits;
    public const int blackQueen = blackDecimals + queenUnits;
    public const int blackRook = blackDecimals + rookUnits;
    public const int blackBishop = blackDecimals + bishopUnits;
    public const int blackNight = blackDecimals + nightUnits;
    public const int blackPawn = blackDecimals + pawnUnits;

    public const int whiteKingPlusBishop = whiteKing + whiteBishop;
    public const int whiteKingPlusNight = whiteKing + whiteNight;

    public const int blackKingPlusBishop = blackKing + blackBishop;
    public const int blackKingPlusNight = blackKing + blackNight;

    public const int baseMaterial = kingUnits + queenUnits + 2 * (rookUnits + bishopUnits + nightUnits) + 8 * pawnUnits;
    public const int fullWhiteMaterial = 16 * whiteDecimals + baseMaterial;
    public const int fullBlackMaterial = 16 * blackDecimals + baseMaterial;

        #endregion

        #region Game modes

    //public enum GameModes { PlayerVsComputer = 0, PlayerVsPlayer = 1, ComputerVsComputer = 2, CheckMoveList = 3 }; //! PERFECT!!!
    public enum GameModes { ComputerVsComputer = 0, PlayerVsComputer = 1, PlayerVsPlayer = 2, CheckMoveList = 3, FinishGame = 4, ThroughMoves = 5 };
    public static GameModes gameMode = GameModes.ComputerVsComputer;  // by instancing

    public static string choiseGameModeToFinishGameFromMove;
    public static string changeGameModeByEventually;
    public static int changeGameModeBy;
    public static bool hadNewGame = false;

    //public static List<string> gameModes = new List<string>() { "1", "2", "0", "3" }; //! Perfect!
    public static List<string> gameModes = new List<string>() { "0", "1", "2", "3", "f", "z" };

    public static string choise; // useless

        #endregion

        #region Menu

    public static ConsoleColor menuBackgroundColor = ConsoleColor.Black;
    public static ConsoleColor menuForegroundColorWhileNotChosen = ConsoleColor.Yellow;
    public static ConsoleColor menuForegroundColorForCurrentMainText = ConsoleColor.Red;
    public static ConsoleColor menuForegroundColorWhileChosen = ConsoleColor.Green;
    public static ConsoleColor menuColorForPrinting = ConsoleColor.Green;
    public static ConsoleColor menuArrows = ConsoleColor.Yellow;
    public static ConsoleColor menuBlueColor = ConsoleColor.Blue;
    public static ConsoleColor menuColorForFirstText = ConsoleColor.Magenta;
    public static ConsoleColor menuColorOfOuterFrameBackgroundMenu = ConsoleColor.Blue;
    public static ConsoleColor menuColorOfOuterFrameForegroundMenu = ConsoleColor.Blue;

        #endregion

        #region Legal, checks and avoids

    public static bool canJump;

    public static int king;
    public static int kingRow;
    public static int kingColumn;
    public static int oppositeKing;
    public static int oppositeKingRow;
    public static int oppositeKingColumn;
    public static int rook;
    public static int theRow;
    public static int rowChange;
    public static int theColumn;
    public static int columnChange;
    public static int figureRow;
    public static int figureColumn;

    public static int theField;

    public static int rowMovement;
    public static int columnMovement;

    public static bool makeNextCheck;

    public static bool oppositeCheck;
    public static bool oppositeAvoid;

    public static List<List<int>> lookOnlyThisPositions = new List<List<int>>();
    public static int figureIndex;

    public static bool willBeUnderCheck = false;

    public static int thisKing;
    public static int otherKing;

    public static int toThisField;

    public static List<List<int>> takenFigures = new List<List<int>>();
    public static int[] nextTakenFigure = new int[2] { 0, 0 };
    public static int takenColor; // useless

        #endregion

        #region Newest

    public static bool drawAfterMakeMove = false;

    public static bool printBeforeFirstMove = true;

    public static bool lastTakes = false;
    public static int lastExchangeDifference = 0;
    public static List<List<List<int>>> lastSavePositions = new List<List<List<int>>>();

    public static List<List<int>> candidates = new List<List<int>>();
    public static int candidateFigures;
    public static int candidateFigureMoves;

    public static int[] allPossibleMoves = new int[] { 0, 0 };
    public static List<List<int>> saveOneNotPerfectMove = new List<List<int>>();



        #endregion

        #region Others



        #endregion

        #region Players

    public static int playWith = 0;
    public static int oppositePlayWith = 1 - playWith;
    public static string changePlayWith = "c";

    public static int playerToMove = 0;
    public static int oppositePlayer = 1;

    public static int currentMove = 0;

        #endregion

        #region Talking

    public static StringBuilder sentence = new StringBuilder();
    public static SpeechSynthesizer say;

    public static bool sound = true;
    public static string changeSound = "s";
    
        #endregion

        #region Print

    public static List<int> lookingAngles = new List<int>();
    public static int lookingAngle;

    public static string emptyBlackboardRow = new string(' ', 106); // it was 104

    public static string outerHorizontalEmptyEnds = new string(' ', 4);
    public static string outerHorizontalEmptyMiddle = new string(' ', 40);
    public static string outerHorizontalEmpty = new string(' ', 48);
    public static string outerEmptyByVertical = new string(' ', 3);

    public static List<string> outerHorizontalTextLine = new List<string>() { "      a    b    c    d    e    f    g    h      ",
                                                                              "      1    2    3    4    5    6    7    8      ", 
                                                                              "      h    g    f    e    d    c    b    a      ",
                                                                              "      8    7    6    5    4    3    2    1      " };

    public static string internalHorizontalEmpty = new string(' ', 42);
    public static int outerHorizontalSymbolByVertical;
    public static string fieldEmptyByHorizontal = new string(' ', 5);
    public static int figureInField;

    //! Не променяй последователността на бутоните за ротация!!!
    public static List<string> rotations = new List<string>() { "d", "r", "t", "l", "D", "R", "T", "L" };
    public static int rotate;

    public static bool blindfold = false;
    public static string changeBlindfold = "b";

    public static string topHelp = string.Format(". =? = e4 e7-e8=B+ e:f6 exf8=R= e7xf8=N+= Be5 Nef6 Q3xf7 Qe3e4 Re3-e7# Kxe2 Ke1xe2 0-0 0-0-0", 
                                                                                                rotations[0], rotations[1], rotations[2], rotations[3]);
    public static string bottomHelp = string.Format("New {0},{1},{2},{3} pieCes Blindfold Sound DLRoTation",
                                                                        gameModes[0], gameModes[1], gameModes[2], gameModes[3], changePlayWith);

    public static string playAgain = "Choose mode and start a new game...";

        #endregion
    
        #region Randoms

    public static Random randomGenerator = new Random();

    public static int randomTakesSymbol;

    public static int[] randomResign = new int[] { 1, 1 };
    public static int[] randomResignFrom = new int[] { 100, 100 };

    public static int[] randomAcceptDrawByAgreement = new int[] { 1, 1 };
    public static int[] randomAcceptDrawByAgreementFrom = new int[] { 100, 100 };
    public static int[] randomOffersDrawByAgreement = new int[] { 1, 1 };
    public static int[] randomOffersDrawByAgreementFrom = new int[] { 100, 100 };

    public static int[] randomDrawByMaterial = new int[] { 100, 100 };
    public static int[] randomDrawByMaterialFrom = new int[] { 100, 100 };

    public static int[] randomDrawByRepetition = new int[] { 100, 100 };
    public static int[] randomDrawByRepetitionFrom = new int[] { 100, 100 };

    public static int[] randomDrawByFiftyRule = new int[] { 100, 100 };
    public static int[] randomDrawByFiftyRuleFrom = new int[] { 100, 100 };

        #endregion

        #region Read Move

    public static string gotMoveReserve = "";
    public static string gotMove = "";

    public static Queue<char> readMove = new Queue<char>();
    public static string specialFigures = "NBRQK";
    public static string allColumns = "abcdefgh";

            #region Castles

    public static string someCastle = "O-O";
    public static string castleKingsideFree = "O-O";
    public static string castleKingsideCheck = "O-O+";
    public static string castleKingsideDraw = "O-O=";
    public static string castleKingsideCheckAndDraw = "O-O+=";
    public static string castleKingsideCheckmate = "O-O#";
    public static string castleQueensideFree = "O-O-O";
    public static string castleQueensideCheck = "O-O-O+";
    public static string castleQueensideDraw = "O-O-O=";
    public static string castleQueensideCheckAndDraw = "O-O+=";
    public static string castleQueensideCheckmate = "O-O-O#";
    public enum Castles { noCastle, castleKingsideFree, castleKingsideCheck, castleKingsideDraw, castleKingsideCheckAndDraw, castleKingsideCheckmate, castleQueensideFree, castleQueensideCheck, castleQueensideDraw, castleQueensideCheckAndDraw, castleQueensideCheckmate };
    public static Castles castle;
    public static int castleRow;
    public static int indexOfCastleRook;
    public static List<List<bool>> castlePossibility = new List<List<bool>>();
    public static bool castleKingside = false;
    public static bool castleQueenside = false;

    public static int stateForCastle = 0; // няма нужда от тази променлива
    public static List<List<bool>> castling = new List<List<bool>>();
    public static bool castled = false;

            #endregion

    public static List<List<List<int>>> savePositions = new List<List<List<int>>>();

        #region Symbols

    public static char moveSymbol = '-';
    public static char takeSymbol = 'x';
    public static char enPassantSymbol = ':';
    public static char checkSymbol = '+';
    public static char drawSymbol = '=';
    public static char exchangeSymbol = '=';
    public static char checkmateSymbol = '#';
    public static char resignSymbol = '.';

        #endregion

    public enum States { Free, Check, Draw, Checkmate, Resign };
    public static States realState = States.Free;
    public static States give;

    public static bool takes;

    public static bool exchange = false;
    public static int exchangeWith = 0;

    public static string pressed;

    public static string inappropriateMoveList;
    public static string[] inappropriateMoveListArray; // make! zeroizing on the both places, if it possible

    public static StringBuilder buildTextOfMove = new StringBuilder();

    public static bool givePossibleDraw = false;
    public static bool givePossibleResign = false;
    public static bool offersDrawByAgreement = false;
    public static bool buttonPressed = false;
    public static bool giveDrawAfterMove = false;
    public static bool answerTheDrawQuestion = false;

    public static bool pressedSpecialButton = false;
    public static bool pressedNonSpecialButton = false;

    public static List<string> moveList = new List<string>();

    public static List<List<List<List<int>>>> possibleMoves = new List<List<List<List<int>>>>();

    //public static List<List<List<int>>> possibleMoves = new List<List<List<int>>>();

        #endregion

        #region Resign

    public static string resign = ".";

        #endregion

        #region Timers

    public static DateTime startTime;
    public static TimeSpan duration;

    public static int timeAfterChoiseFinishGameFromMoveList = 1000;
    public static int timeAfterChoiseGameModeAfterEndingList = 1000;
    public static int timeBeforeFirstMoveFromList = 1500;
    public static int timeAfterRotationOrBlindfoldChangeBeforeNextMoveFromListOrPC = 1500;
    public static int timeBeforeNextMoveFromList = 2000;
    public static bool hadRotation = false;
    public static bool hadBlindfoldChange = false;

    public static int timeBetweenPrintMoveAndMoveFigure = 500;

    public static int timePCThinksMove = 2000;

        #endregion

        #region Tests

    public static int sets = 0;                         // by instance
    public static int oldSets = 0;                      // by instance
    public static int[] wins = new int[2] { 0, 0 };     // by instance
    public static int draws = 0;                        // by instance
    public static int[] loses = new int[2] { 0, 0 };    // by instance
    public static int[] resigns = new int[2] { 0, 0 };  // by instance

    public static int testCounterOf = 0;

    public static int ti1;
    public static int ti2;
    public static int ti3;
    public static int ti4;
    public static int ti5;

    public static bool tb1;
    public static bool tb2;
    public static bool tb3;
    public static bool tb4;
    public static bool tb5;

    public static string erori = "before";

        #endregion

        #region Zeroizing

    public static bool zeroizePrints = false;
    public static bool zeroizeWaits = false;
    public static bool zeroizeSounds = false;

        #endregion

    //public static int[,] defaultBattlefield = new int[,]     {   {blackRook, blackNight, blackBishop, blackQueen, blackKing, blackBishop, blackNight, blackRook},
    //                                        {blackPawn, blackPawn, blackPawn, blackPawn, blackPawn, blackPawn, blackPawn, blackPawn},
    //                                        {emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField},
    //                                        {emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField},
    //                                        {emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField},
    //                                        {emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField, emptyField},
    //                                        {whitePawn, whitePawn, whitePawn, whitePawn, whitePawn, whitePawn, whitePawn, whitePawn},
    //                                        {whiteRook, whiteNight, whiteBishop, whiteQueen, whiteKing, whiteBishop, whiteNight, whiteRook}     };

    #endregion

    #region Main function / Главна функция

    public static void Main() // Главна функция 
    {
        //MenuAtFirstPage();

        startTime = DateTime.Now;
        PimaryInitialization();

        do
        {
            sets++;
            Play();
        } while (true);
    }

    #endregion

    #region Initials / Инициализации

    public static void PimaryInitialization() // Първична инициализация 
    {
        finishMoveInMoveList = false;
        //finishGameFromMove = -1; //! zabraneno da se izpylnqva

        //emptyRawMoveList = false;
        //emptyInappropriateMoveListArray = false;
        //emptyMoveList = false;

        urongMove = false;
        unwantedMove = false;
        unfinishedList = false;

        enPassantPreparing = -9;

        drawQuestionOnMove = -3;

        #region Game difficulties

        //! (0-2) попълва Random-ите и на двамата, иначе ЗАДЪЛЖИТЕЛНО поотделно (3-5) и (6-8), където White: 3A, 4H, 5N - 6A, 7H, 8N : Black
        //GameDifficulty(2); // N - N

        //GameDifficulty(2);

        GameDifficulty(3);
        GameDifficulty(6);

        #endregion

        #region Newest

        drawAfterMakeMove = false;

        printBeforeFirstMove = true;

        lastTakes = false;
        lastExchangeDifference = 0;

        allPossibleMoves[0] = 0;
        allPossibleMoves[1] = 0;

        saveOneNotPerfectMove.Clear();
        saveOneNotPerfectMove.Add(new List<int>());
        saveOneNotPerfectMove.Add(new List<int>());

        givePossibleDraw = false;
        givePossibleResign = false;
        offersDrawByAgreement = false;
        buttonPressed = false;
        giveDrawAfterMove = false;
        answerTheDrawQuestion = false;

        pressedSpecialButton = false;
        pressedNonSpecialButton = false;

        drawKind = "";

        mateInOne = false;
        mateInOneWithFigure = 0;
        mateInOneWithFigureOnMovement = 0;

        maxGoodMoveOfAllFigures = 0;
        maxGoodMoveOfCurrentFigure = 0;
        maxGoodMoveOfCurrentFigureIndex = 0;
        maxRepetition = 0;
        currentBattlefield = "";
        maxRepetitionWithCurrentBattlefield = 0;
        perfectFigure = 0;
        perfectFigureIndex = 0;
        perfectMovementIndexOfPerfectFigure = 0;
        howManyPerfectFigures = 0;
        howManyPerfectMovesOfThisPerfectFigure = 0;

        #endregion

        #region Console

        Console.CursorVisible = false;
        //Console.WindowWidth = consoleWidth;
        Console.BufferWidth = consoleWidth;
        //Console.WindowHeight = consoleHeight;
        Console.BufferHeight = consoleHeight;
        Console.BackgroundColor = colorOfMovesBackground;
        Console.ForegroundColor = colorOfMovesForeground;
        Console.Clear();
        Console.SetCursorPosition(0, 0);

        #endregion

        #region Game modes

        hadNewGame = false;

        #endregion

        #region Read move

        gotMove = "";
        readMove.Clear();

        takes = false;
        exchange = false;
        exchangeWith = 0;

        give = States.Free;
        realState = States.Free;

        buildTextOfMove.Clear();

        #endregion

        #region Check for check

        willBeUnderCheck = false;

        #endregion

        #region Players

        playWith = 0;
        oppositePlayWith = 1 - playWith;

        playerToMove = 0;
        oppositePlayer = 1 - playerToMove;

        #endregion

        #region Blindfold

        blindfold = false;

        #endregion

        #region Sound and talking

        sound = true;
        sentence.Clear();

        #endregion

        #region Taken figures

        nextTakenFigure[0] = 0;
        nextTakenFigure[1] = 0;

        #endregion

        #region Save battlefields

        saveCurrentBattlefield.Clear();
        saveBattlefields.Clear();
        matches.Clear();
        maxMatches = 0;
        maxMatchesEventually = 0;

        passiveMoves[0] = 0;
        passiveMoves[1] = 0;

        #endregion

        #region Zeroizing

        zeroizePrints = false;
        zeroizeWaits = false;
        zeroizeSounds = false;

        #endregion

        #region Table

        battlefield[0, 0] = battlefield[0, 7] = whiteDecimals + rookUnits;
        battlefield[0, 1] = battlefield[0, 6] = whiteDecimals + nightUnits;
        battlefield[0, 2] = battlefield[0, 5] = whiteDecimals + bishopUnits;
        battlefield[0, 3] = whiteDecimals + queenUnits;
        battlefield[0, 4] = whiteDecimals + kingUnits;

        for (col = 0; col <= 7; col++)
        {
            battlefield[1, col] = whiteDecimals + pawnUnits;
            battlefield[6, col] = blackDecimals + pawnUnits;
        }

        for (ro = 2; ro <= 5; ro++)
            for (col = 0; col <= 7; col++)
                battlefield[ro, col] = 0;

        battlefield[7, 0] = battlefield[7, 7] = blackDecimals + rookUnits;
        battlefield[7, 1] = battlefield[7, 6] = blackDecimals + nightUnits;
        battlefield[7, 2] = battlefield[7, 5] = blackDecimals + bishopUnits;
        battlefield[7, 3] = blackDecimals + queenUnits;
        battlefield[7, 4] = blackDecimals + kingUnits;

        #endregion

        #region Figures

        figures.Clear();

        #region White

        figures.Add(new List<List<int>>(0));

        figures[0].Add(new List<int>(0));
        figures[0].Add(new List<int>(1));
        figures[0].Add(new List<int>(2));

        figures[0][0].Add(whiteDecimals + kingUnits);
        figures[0][0].Add(whiteDecimals + queenUnits);
        figures[0][0].Add(whiteDecimals + rookUnits);
        figures[0][0].Add(whiteDecimals + rookUnits);
        figures[0][0].Add(whiteDecimals + bishopUnits);
        figures[0][0].Add(whiteDecimals + bishopUnits);
        figures[0][0].Add(whiteDecimals + nightUnits);
        figures[0][0].Add(whiteDecimals + nightUnits);
        for (counterOfWhitePawn = 0; counterOfWhitePawn <= 7; counterOfWhitePawn++)
            figures[0][0].Add(whiteDecimals + pawnUnits);

        for (rowOfWhiteSpecialFigure = 0; rowOfWhiteSpecialFigure <= 7; rowOfWhiteSpecialFigure++)
            figures[0][1].Add(0);
        for (rowOfWhitePawn = 0; rowOfWhitePawn <= 7; rowOfWhitePawn++)
            figures[0][1].Add(1);

        figures[0][2].Add(4);
        figures[0][2].Add(3);
        figures[0][2].Add(0);
        figures[0][2].Add(7);
        figures[0][2].Add(2);
        figures[0][2].Add(5);
        figures[0][2].Add(1);
        figures[0][2].Add(6);
        for (columnOfWhitePawn = 0; columnOfWhitePawn <= 7; columnOfWhitePawn++)
            figures[0][2].Add(columnOfWhitePawn);

        #endregion

        #region Black

        figures.Add(new List<List<int>>(1));

        figures[1].Add(new List<int>(0));
        figures[1].Add(new List<int>(1));
        figures[1].Add(new List<int>(2));

        figures[1][0].Add(blackDecimals + kingUnits);
        figures[1][0].Add(blackDecimals + queenUnits);
        figures[1][0].Add(blackDecimals + rookUnits);
        figures[1][0].Add(blackDecimals + rookUnits);
        figures[1][0].Add(blackDecimals + bishopUnits);
        figures[1][0].Add(blackDecimals + bishopUnits);
        figures[1][0].Add(blackDecimals + nightUnits);
        figures[1][0].Add(blackDecimals + nightUnits);
        for (counterOfBlackPawn = 0; counterOfBlackPawn <= 7; counterOfBlackPawn++)
            figures[1][0].Add(blackDecimals + pawnUnits);

        for (rowOfBlackSpecialFigure = 0; rowOfBlackSpecialFigure <= 7; rowOfBlackSpecialFigure++)
            figures[1][1].Add(7);
        for (rowOfBlackPawn = 0; rowOfBlackPawn <= 7; rowOfBlackPawn++)
            figures[1][1].Add(6);

        figures[1][2].Add(4);
        figures[1][2].Add(3);
        figures[1][2].Add(0);
        figures[1][2].Add(7);
        figures[1][2].Add(2);
        figures[1][2].Add(5);
        figures[1][2].Add(1);
        figures[1][2].Add(6);
        for (columnOfBlackPawn = 0; columnOfBlackPawn <= 7; columnOfBlackPawn++)
            figures[1][2].Add(columnOfBlackPawn);

        #endregion

        #region Materials

        materials.Clear();

        materials.Add(fullWhiteMaterial);
        materials.Add(fullBlackMaterial);

        #endregion

        #region Taken figures

        takenFigures.Clear();

        takenFigures.Add(new List<int>());
        takenFigures.Add(new List<int>());

        #endregion

        #endregion

        #region Looking angles

        lookingAngles.Clear();

        lookingAngles.Add(0);
        if (gameMode == GameModes.PlayerVsPlayer)
            lookingAngles.Add(2);
        else
            lookingAngles.Add(0);

        #endregion

        #region Moves

        currentMove = 0;

        moveList.Clear();

        possibleMoves.Clear();
        possibleMoves.Add(new List<List<List<int>>>());
        possibleMoves.Add(new List<List<List<int>>>());

        #region Last moves

        lastMoves.Clear();

        lastMoves.Add(new List<string>(0));
        lastMoves.Add(new List<string>(1));

        #endregion

        #region Save positions

        savePositions.Clear();

        savePositions.Add(new List<List<int>>(0));
        savePositions.Add(new List<List<int>>(1));

        savePositions[0].Add(new List<int>(0));
        savePositions[0].Add(new List<int>(1));

        savePositions[1].Add(new List<int>(0));
        savePositions[1].Add(new List<int>(1));

        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);

        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);

        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);

        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);


        lastSavePositions.Clear();

        lastSavePositions.Add(new List<List<int>>(0));
        lastSavePositions.Add(new List<List<int>>(1));

        lastSavePositions[0].Add(new List<int>(0));
        lastSavePositions[0].Add(new List<int>(1));

        lastSavePositions[1].Add(new List<int>(0));
        lastSavePositions[1].Add(new List<int>(1));

        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);

        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);

        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);

        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);

        #endregion

        #region Look only this positions

        lookOnlyThisPositions.Clear();

        lookOnlyThisPositions.Add(new List<int>(0));
        lookOnlyThisPositions.Add(new List<int>(1));
        lookOnlyThisPositions.Add(new List<int>(2));

        #endregion

        #region Castle

        stateForCastle = 0;

        castled = false;

        castling.Clear();
        castling.Add(new List<bool>() { false, false });
        castling.Add(new List<bool>() { false, false });

        castleKingside = false;
        castleQueenside = false;

        castle = Castles.noCastle;

        castlePossibility.Clear();

        castlePossibility.Add(new List<bool>(0));
        castlePossibility.Add(new List<bool>(1));

        castlePossibility[0].Add(true);
        castlePossibility[0].Add(true);
        castlePossibility[0].Add(true);
        castlePossibility[0].Add(true);

        castlePossibility[1].Add(true);
        castlePossibility[1].Add(true);
        castlePossibility[1].Add(true);
        castlePossibility[1].Add(true);

        #endregion

        #endregion
    }

    public static void StartingPosition() // Инициализация в началото на всяка нова игра 
    {
        finishMoveInMoveList = false;
        //finishGameFromMove = -1; //! zabraneno da se izpylnqva

        //emptyRawMoveList = false;
        //emptyInappropriateMoveListArray = false;
        //emptyMoveList = false;

        urongMove = false;
        unwantedMove = false;
        unfinishedList = false;

        enPassantPreparing = -9;

        drawQuestionOnMove = -3;

        erori = "before";

        #region Game difficulties

        //! (0-2) попълва Random-ите и на двамата, иначе ЗАДЪЛЖИТЕЛНО поотделно (3-5) и (6-8), където White: 3A, 4H, 5N - 6A, 7H, 8N : Black
        //GameDifficulty(2); // N - N
        //GameDifficulty(3);
        //GameDifficulty(6);

        #endregion

        #region Newest

        drawAfterMakeMove = false;

        printBeforeFirstMove = true;

        lastTakes = false;
        lastExchangeDifference = 0;

        allPossibleMoves[0] = 0;
        allPossibleMoves[1] = 0;

        saveOneNotPerfectMove.Clear();
        saveOneNotPerfectMove.Add(new List<int>());
        saveOneNotPerfectMove.Add(new List<int>());

        givePossibleDraw = false;
        givePossibleResign = false;
        offersDrawByAgreement = false;
        buttonPressed = false;
        giveDrawAfterMove = false;
        answerTheDrawQuestion = false;

        pressedSpecialButton = false;
        pressedNonSpecialButton = false;

        drawKind = "";

        mateInOne = false;
        mateInOneWithFigure = 0;
        mateInOneWithFigureOnMovement = 0;

        maxGoodMoveOfAllFigures = 0;
        maxGoodMoveOfCurrentFigure = 0;
        maxGoodMoveOfCurrentFigureIndex = 0;
        maxRepetition = 0;
        currentBattlefield = "";
        maxRepetitionWithCurrentBattlefield = 0;
        perfectFigure = 0;
        perfectFigureIndex = 0;
        perfectMovementIndexOfPerfectFigure = 0;
        howManyPerfectFigures = 0;
        howManyPerfectMovesOfThisPerfectFigure = 0;

        #endregion

        #region Console

        Console.CursorVisible = false;
        //Console.WindowWidth = consoleWidth;
        Console.BufferWidth = consoleWidth;
        //Console.WindowHeight = consoleHeight;
        Console.BufferHeight = consoleHeight;
        Console.BackgroundColor = colorOfMovesBackground;
        Console.ForegroundColor = colorOfMovesForeground;
        Console.Clear();
        Console.SetCursorPosition(0, 0);

        #endregion

        #region Game modes

        hadNewGame = false;

        #endregion

        #region Read move

        gotMove = "";
        readMove.Clear();

        takes = false;
        exchange = false;
        exchangeWith = 0;

        give = States.Free;
        realState = States.Free;

        buildTextOfMove.Clear();

        #endregion

        #region Check for check

        willBeUnderCheck = false;

        #endregion

        #region Players

        playWith = 0;
        oppositePlayWith = 1 - playWith;

        playerToMove = 0;
        oppositePlayer = 1 - playerToMove;

        #endregion

        #region Blindfold

        blindfold = false;

        #endregion

        #region Sound and talking

        sound = true;
        sentence.Clear();

        #endregion

        #region Taken figures

        nextTakenFigure[0] = 0;
        nextTakenFigure[1] = 0;

        #endregion

        #region Save battlefields

        saveCurrentBattlefield.Clear();
        saveBattlefields.Clear();
        matches.Clear();
        maxMatches = 0;
        maxMatchesEventually = 0;

        passiveMoves[0] = 0;
        passiveMoves[1] = 0;

        #endregion

        #region Zeroizing

        zeroizePrints = false;
        zeroizeWaits = false;
        zeroizeSounds = false;

        #endregion

        #region Table

        //battlefield[0, 0] = battlefield[0, 7] = whiteRook;
        //battlefield[0, 1] = battlefield[0, 6] = whiteNight;
        //battlefield[0, 2] = battlefield[0, 5] = whiteBishop;
        //battlefield[0, 3] = whiteQueen;
        //battlefield[0, 4] = whiteKing;

        //for (col = 0; col <= 7; col++)
        //{
        //    battlefield[1, col] = whitePawn;
        //    battlefield[6, col] = blackPawn;
        //}

        //for (ro = 2; ro <= 5; ro++)
        //    for (col = 0; col <= 7; col++)
        //        battlefield[ro, col] = emptyField;

        //battlefield[7, 0] = battlefield[7, 7] = blackRook;
        //battlefield[7, 1] = battlefield[7, 6] = blackNight;
        //battlefield[7, 2] = battlefield[7, 5] = blackBishop;
        //battlefield[7, 3] = blackQueen;
        //battlefield[7, 4] = blackKing;

        battlefield[0, 0] = whiteRook;
        battlefield[0, 1] = whiteNight;
        battlefield[0, 2] = whiteBishop;
        battlefield[0, 3] = whiteQueen;
        battlefield[0, 4] = whiteKing;
        battlefield[0, 5] = whiteBishop;
        battlefield[0, 6] = whiteNight;
        battlefield[0, 7] = whiteRook;

        battlefield[1, 0] = whitePawn;
        battlefield[1, 1] = whitePawn;
        battlefield[1, 2] = whitePawn;
        battlefield[1, 3] = whitePawn;
        battlefield[1, 4] = whitePawn;
        battlefield[1, 5] = whitePawn;
        battlefield[1, 6] = whitePawn;
        battlefield[1, 7] = whitePawn;

        battlefield[2, 0] = emptyField;
        battlefield[2, 1] = emptyField;
        battlefield[2, 2] = emptyField;
        battlefield[2, 3] = emptyField;
        battlefield[2, 4] = emptyField;
        battlefield[2, 5] = emptyField;
        battlefield[2, 6] = emptyField;
        battlefield[2, 7] = emptyField;

        battlefield[3, 0] = emptyField;
        battlefield[3, 1] = emptyField;
        battlefield[3, 2] = emptyField;
        battlefield[3, 3] = emptyField;
        battlefield[3, 4] = emptyField;
        battlefield[3, 5] = emptyField;
        battlefield[3, 6] = emptyField;
        battlefield[3, 7] = emptyField;

        battlefield[4, 0] = emptyField;
        battlefield[4, 1] = emptyField;
        battlefield[4, 2] = emptyField;
        battlefield[4, 3] = emptyField;
        battlefield[4, 4] = emptyField;
        battlefield[4, 5] = emptyField;
        battlefield[4, 6] = emptyField;
        battlefield[4, 7] = emptyField;

        battlefield[5, 0] = emptyField;
        battlefield[5, 1] = emptyField;
        battlefield[5, 2] = emptyField;
        battlefield[5, 3] = emptyField;
        battlefield[5, 4] = emptyField;
        battlefield[5, 5] = emptyField;
        battlefield[5, 6] = emptyField;
        battlefield[5, 7] = emptyField;

        battlefield[6, 0] = blackPawn;
        battlefield[6, 1] = blackPawn;
        battlefield[6, 2] = blackPawn;
        battlefield[6, 3] = blackPawn;
        battlefield[6, 4] = blackPawn;
        battlefield[6, 5] = blackPawn;
        battlefield[6, 6] = blackPawn;
        battlefield[6, 7] = blackPawn;

        battlefield[7, 0] = blackRook;
        battlefield[7, 1] = blackNight;
        battlefield[7, 2] = blackBishop;
        battlefield[7, 3] = blackQueen;
        battlefield[7, 4] = blackKing;
        battlefield[7, 5] = blackBishop;
        battlefield[7, 6] = blackNight;
        battlefield[7, 7] = blackRook;

        #endregion

        #region Figures

        figures.Clear();

            #region White

        figures.Add(new List<List<int>>(0));

        figures[0].Add(new List<int>(0));
        figures[0].Add(new List<int>(1));
        figures[0].Add(new List<int>(2));

        figures[0][0].Add(whiteKing);
        figures[0][0].Add(whiteQueen);
        figures[0][0].Add(whiteRook);
        figures[0][0].Add(whiteRook);
        figures[0][0].Add(whiteBishop);
        figures[0][0].Add(whiteBishop);
        figures[0][0].Add(whiteNight);
        figures[0][0].Add(whiteNight);
        for (counterOfWhitePawn = 0; counterOfWhitePawn <= 7; counterOfWhitePawn++)
            figures[0][0].Add(whitePawn);

        for (rowOfWhiteSpecialFigure = 0; rowOfWhiteSpecialFigure <= 7; rowOfWhiteSpecialFigure++)
            figures[0][1].Add(0);
        for (rowOfWhitePawn = 0; rowOfWhitePawn <= 7; rowOfWhitePawn++)
            figures[0][1].Add(1);

        figures[0][2].Add(4);
        figures[0][2].Add(3);
        figures[0][2].Add(0);
        figures[0][2].Add(7);
        figures[0][2].Add(2);
        figures[0][2].Add(5);
        figures[0][2].Add(1);
        figures[0][2].Add(6);
        for (columnOfWhitePawn = 0; columnOfWhitePawn <= 7; columnOfWhitePawn++)
            figures[0][2].Add(columnOfWhitePawn);

            #endregion

            #region Black

        figures.Add(new List<List<int>>(1));

        figures[1].Add(new List<int>(0));
        figures[1].Add(new List<int>(1));
        figures[1].Add(new List<int>(2));

        figures[1][0].Add(blackKing);
        figures[1][0].Add(blackQueen);
        figures[1][0].Add(blackRook);
        figures[1][0].Add(blackRook);
        figures[1][0].Add(blackBishop);
        figures[1][0].Add(blackBishop);
        figures[1][0].Add(blackNight);
        figures[1][0].Add(blackNight);
        for (counterOfBlackPawn = 0; counterOfBlackPawn <= 7; counterOfBlackPawn++)
            figures[1][0].Add(blackPawn);

        for (rowOfBlackSpecialFigure = 0; rowOfBlackSpecialFigure <= 7; rowOfBlackSpecialFigure++)
            figures[1][1].Add(7);
        for (rowOfBlackPawn = 0; rowOfBlackPawn <= 7; rowOfBlackPawn++)
            figures[1][1].Add(6);

        figures[1][2].Add(4);
        figures[1][2].Add(3);
        figures[1][2].Add(0);
        figures[1][2].Add(7);
        figures[1][2].Add(2);
        figures[1][2].Add(5);
        figures[1][2].Add(1);
        figures[1][2].Add(6);
        for (columnOfBlackPawn = 0; columnOfBlackPawn <= 7; columnOfBlackPawn++)
            figures[1][2].Add(columnOfBlackPawn);

            #endregion

            #region Materials
        
        materials.Clear();

        materials.Add(fullWhiteMaterial);
        materials.Add(fullBlackMaterial);

            #endregion

            #region Taken figures

        takenFigures.Clear();

        takenFigures.Add(new List<int>());
        takenFigures.Add(new List<int>());

            #endregion

        #endregion

        #region Looking angles

        lookingAngles.Clear();

        lookingAngles.Add(0);
        if (gameMode == GameModes.PlayerVsPlayer)
            lookingAngles.Add(2);
        else
            lookingAngles.Add(0);

        #endregion

        #region Moves

        currentMove = 0;

        moveList.Clear();

        possibleMoves.Clear();
        possibleMoves.Add(new List<List<List<int>>>());
        possibleMoves.Add(new List<List<List<int>>>());

            #region Last moves

        lastMoves.Clear();

        lastMoves.Add(new List<string>(0));
        lastMoves.Add(new List<string>(1));

            #endregion

            #region Save positions

        savePositions.Clear();

        savePositions.Add(new List<List<int>>(0));
        savePositions.Add(new List<List<int>>(1));

        savePositions[0].Add(new List<int>(0));
        savePositions[0].Add(new List<int>(1));

        savePositions[1].Add(new List<int>(0));
        savePositions[1].Add(new List<int>(1));

        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);
        savePositions[0][0].Add(0);

        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);
        savePositions[0][1].Add(0);

        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);
        savePositions[1][0].Add(0);

        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);
        savePositions[1][1].Add(0);


        lastSavePositions.Clear();

        lastSavePositions.Add(new List<List<int>>(0));
        lastSavePositions.Add(new List<List<int>>(1));

        lastSavePositions[0].Add(new List<int>(0));
        lastSavePositions[0].Add(new List<int>(1));

        lastSavePositions[1].Add(new List<int>(0));
        lastSavePositions[1].Add(new List<int>(1));

        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);
        lastSavePositions[0][0].Add(0);

        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);
        lastSavePositions[0][1].Add(0);

        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);
        lastSavePositions[1][0].Add(0);

        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);
        lastSavePositions[1][1].Add(0);

            #endregion

            #region Look only this positions
        
        lookOnlyThisPositions.Clear();

        lookOnlyThisPositions.Add(new List<int>(0));
        lookOnlyThisPositions.Add(new List<int>(1));
        lookOnlyThisPositions.Add(new List<int>(2));

            #endregion

            #region Castle

        stateForCastle = 0;

        castled = false;

        castling.Clear();
        castling.Add(new List<bool>() { false, false });
        castling.Add(new List<bool>() { false, false });

        castleKingside = false;
        castleQueenside = false;

        castle = Castles.noCastle;

        castlePossibility.Clear();

        castlePossibility.Add(new List<bool>() { true, true, true, true });
        castlePossibility.Add(new List<bool>() { true, true, true, true });

        //castlePossibility.Add(new List<bool>(0));
        //castlePossibility.Add(new List<bool>(1));

        //castlePossibility[0].Add(true);
        //castlePossibility[0].Add(true);
        //castlePossibility[0].Add(true);
        //castlePossibility[0].Add(true);

        //castlePossibility[1].Add(true);
        //castlePossibility[1].Add(true);
        //castlePossibility[1].Add(true);
        //castlePossibility[1].Add(true);

            #endregion

        #endregion
    }

    public static void GameDifficulty(int changeDifficultyTo) // Ниво на трудност на компютърния интелект 
    {
        if (changeDifficultyTo != -1)
        {
            if (changeDifficultyTo <= 2)
            {
                gameBothDifficulty[0] = (Difficulty)changeDifficultyTo;
                gameBothDifficulty[1] = (Difficulty)changeDifficultyTo;
            }
            else if ((3 <= changeDifficultyTo) && (changeDifficultyTo <= 5))
                gameBothDifficulty[0] = (Difficulty)(changeDifficultyTo % 3);
            else
                gameBothDifficulty[1] = (Difficulty)(changeDifficultyTo % 3);

            for (igd = 0; igd < 2; igd++)
            {
                if (((igd == 0) && (6 <= changeDifficultyTo))
                        || ((igd == 1) && ((3 <= changeDifficultyTo) && (changeDifficultyTo <= 5))))
                    continue;

                switch (changeDifficultyTo % 3)
                {
                    case 0:
                        {
                            randomResign[igd] = 0;
                            randomResignFrom[igd] = 1000000;

                            randomAcceptDrawByAgreement[igd] = 10;
                            randomAcceptDrawByAgreementFrom[igd] = 100;
                            randomOffersDrawByAgreement[igd] = 0;// 1;
                            randomOffersDrawByAgreementFrom[igd] = 10000;

                            randomDrawByMaterial[igd] = 100;
                            randomDrawByMaterialFrom[igd] = 100;

                            randomDrawByRepetition[igd] = 100;// 20;
                            randomDrawByRepetitionFrom[igd] = 100;

                            randomDrawByFiftyRule[igd] = 100;// 10;
                            randomDrawByFiftyRuleFrom[igd] = 100;

                            break;
                        }
                    case 1:
                        {
                            randomResign[igd] = 0;
                            randomResignFrom[igd] = 1000000;

                            randomAcceptDrawByAgreement[igd] = 20;
                            randomAcceptDrawByAgreementFrom[igd] = 100;
                            randomOffersDrawByAgreement[igd] = 0;// 1;
                            randomOffersDrawByAgreementFrom[igd] = 10000;

                            randomDrawByMaterial[igd] = 100;
                            randomDrawByMaterialFrom[igd] = 100;

                            randomDrawByRepetition[igd] = 100;//30;
                            randomDrawByRepetitionFrom[igd] = 100;

                            randomDrawByFiftyRule[igd] = 100;// 40;
                            randomDrawByFiftyRuleFrom[igd] = 100;

                            break;
                        }
                    case 2:
                        {
                            randomResign[igd] = 0;
                            randomResignFrom[igd] = 1000000;

                            randomAcceptDrawByAgreement[igd] = 100;
                            randomAcceptDrawByAgreementFrom[igd] = 100;
                            randomOffersDrawByAgreement[igd] = 0;// 1;
                            randomOffersDrawByAgreementFrom[igd] = 1000000;

                            randomDrawByMaterial[igd] = 100;
                            randomDrawByMaterialFrom[igd] = 100;

                            randomDrawByRepetition[igd] = 100;
                            randomDrawByRepetitionFrom[igd] = 100;

                            randomDrawByFiftyRule[igd] = 100;
                            randomDrawByFiftyRuleFrom[igd] = 100;

                            break;
                        }
                    default: break;
                }
            }
        }
    }

    public static bool FillMoveList() // Зареждане на списъците с всички ходове от файл
    {
        //! Chessmaster Grand Master 10th Edition 1.2.0, The King 3.50 (28.09.2007), Ubisoft Entertainment

        finishMoveInMoveList = false;

        emptyRawMoveList = false;
        emptyInappropriateMoveListArray = false;
        emptyMoveList = false;

        urongMove = false;
        unwantedMove = false;
        unwantedMoves = false;
        unfinishedList = false;

        try
        {
            moveList.Clear();

            File.Delete("readyMoveList.txt");

            //! using (StreamReader readRawMoveList = new StreamReader("rawMoveList.txt", Encoding.GetEncoding("windows-1251")))

            //using (StreamReader readRawMoveList = new StreamReader("#.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("..txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader(";.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("=!=.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("=.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("=F.txt", Encoding.GetEncoding("windows-1251"))) //? Работи коректно и в двата случая:   1. [+=] (един ход)  и   2. [+]  [=] (два последователни)
            //using (StreamReader readRawMoveList = new StreamReader("=M.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("=R.txt", Encoding.GetEncoding("windows-1251"))) //? Работи коректно и в двата случая:   1. [+=] (един ход)  и   2. [+]  [=] (два последователни)
            //using (StreamReader readRawMoveList = new StreamReader("rawMoveList.txt", Encoding.GetEncoding("windows-1251")))

            //using (StreamReader readRawMoveList = new StreamReader("0.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("=!= short q--q.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("+ =!= short.txt", Encoding.GetEncoding("windows-1251")))
            //////using (StreamReader readRawMoveList = new StreamReader("# short.txt", Encoding.GetEncoding("windows-1251"))) //! Намери такъв пример
            //using (StreamReader readRawMoveList = new StreamReader(". short.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader(". short with (=).txt", Encoding.GetEncoding("windows-1251")))
            //////using (StreamReader readRawMoveList = new StreamReader("; short.txt", Encoding.GetEncoding("windows-1251"))) //! Намери такъв пример
            using (StreamReader readRawMoveList = new StreamReader("; short like x.txt", Encoding.GetEncoding("windows-1251")))
            //using (StreamReader readRawMoveList = new StreamReader("short.txt", Encoding.GetEncoding("windows-1251")))

            //using (StreamReader readRawMoveList = new StreamReader("error.txt", Encoding.GetEncoding("windows-1251")))

            {
                do
                {
                    inappropriateMoveList = readRawMoveList.ReadLine();
                    if (inappropriateMoveList == null)
                    {
                        emptyRawMoveList = true;
                        return true;
                    }

                    if (inappropriateMoveList.IndexOf("[") != -1)
                        continue;
                    else
                    {
                        inappropriateMoveList = string.Format("{0}\r\n{1}", inappropriateMoveList, readRawMoveList.ReadToEnd());
                        break;
                    }
                } while (true);

                #region Старо

                //! Старото:
                //inappropriateMoveList = readRawMoveList.ReadToEnd();

                #endregion
            }

            if (inappropriateMoveList == null)
            {
                emptyRawMoveList = true;
                return true;
            }

            inappropriateMoveList = inappropriateMoveList.Replace("ep.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("e.p.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("Ep.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("E.p.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("eP.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("e.P.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("EP.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("E.P.", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("Ep", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("eP", "ep");
            inappropriateMoveList = inappropriateMoveList.Replace("EP", "ep");

            inappropriateMoveList = inappropriateMoveList.Replace(".", " . ");

            inappropriateMoveList = inappropriateMoveList.Replace("–", "-");
            inappropriateMoveList = inappropriateMoveList.Replace("0-0-0", "O-O-O");
            inappropriateMoveList = inappropriateMoveList.Replace("0-0", "O-O");
            inappropriateMoveList = inappropriateMoveList.Replace("(=)", string.Empty);
            inappropriateMoveList = inappropriateMoveList.Replace("?-?", "1/2-1/2");
            
            inappropriateMoveListArray = inappropriateMoveList.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (inappropriateMoveListArray.Length < 1)
            {
                emptyInappropriateMoveListArray = true;
                return true;
            }

            for (ifml = 0; ifml < inappropriateMoveListArray.Length; ifml++)
                if (finishMoveInMoveList 
                    || ((!int.TryParse(inappropriateMoveListArray[ifml].Trim(), out leadingNumberOfMoveIntoList)) 
                        //&& ((5 <= inappropriateMoveListArray[ifml].Trim().Length) //! Устройва ли ни 2<= ...    ???
                        && ((2 <= inappropriateMoveListArray[ifml].Trim().Length) 
                            || (inappropriateMoveListArray[ifml].IndexOf(someCastle) != -1) 
                            || (inappropriateMoveListArray[ifml].IndexOf("1-0") != -1) 
                            || (inappropriateMoveListArray[ifml].IndexOf("0-1") != -1) 
                            || (inappropriateMoveListArray[ifml].IndexOf("/") != -1))))
                {
                    if (!finishMoveInMoveList && (inappropriateMoveListArray[ifml].IndexOf("ep") != -1))
                    {
                        inappropriateMoveListArray[ifml] = inappropriateMoveListArray[ifml].Replace('x', enPassantSymbol);
                        inappropriateMoveListArray[ifml] = inappropriateMoveListArray[ifml].Replace(':', enPassantSymbol);
                        inappropriateMoveListArray[ifml] = inappropriateMoveListArray[ifml].Replace("ep", string.Empty);
                    }

                    moveList.Add(inappropriateMoveListArray[ifml].Trim());

                    if (inappropriateMoveListArray[ifml].IndexOf("1-0") != -1
                        || inappropriateMoveListArray[ifml].IndexOf("0-1") != -1
                            || inappropriateMoveListArray[ifml].IndexOf("/") != -1)
                        finishMoveInMoveList = true;
                }

            if (moveList.Count < 1)
            {
                emptyMoveList = true;
                return false;
            }

            for (ifml = 0; ifml < moveList.Count; ifml++)
            {
                if ((moveList[ifml][moveList[ifml].Length - 1] == drawSymbol)
                    && (ifml < moveList.Count - 1))
                {
                    //moveList[ifml] = string.Format("{0}{1}", moveList[ifml], urongMoveExample);
                    unwantedMoves = true;
                }

                if (moveList[ifml].IndexOf("/") != -1)
                {
                    if (ifml < moveList.Count - 1)
                        unwantedMoves = true;

                    if (ifml == 0)
                        moveList[ifml] = drawByAgreementShort;
                    else
                    {
                        //! = в самото начало е =?=
                        //! =?= в режим CheckMoveList винаги е нов самостоятелен ход
                        //! =S се дава винаги на най-скорошния ход
                        //! =М се дава винаги на най-скорошния ход
                        //! По-логично е (освен когато playerToMove дава + , за да се спаси с =FR) равенството да го поиска този, който е под шах, но работи и при +=FR със закоментиране на следващите 4+1(отдолу) реда

                        if (moveList[ifml - 1].IndexOf(checkSymbol) != -1)
                            moveList[ifml] = drawSymbol.ToString();
                        else
                        {
                            moveList[ifml - 1] = string.Format("{0}{1}", moveList[ifml - 1].Trim(), drawSymbol);
                            moveList.RemoveAt(ifml);
                            ifml--;
                        }
                    }
                }

                if ((moveList[ifml].IndexOf("1-0") != -1) || (moveList[ifml].IndexOf("0-1") != -1)) //! 0 (нула) вече има само в последния победен ход
                {
                    //if (ifml < moveList.Count - 1)
                    //    unwantedMoves = true;

                    if (ifml == 0)
                    {
                        moveList[ifml] = resignSymbol.ToString();
                        if (ifml != moveList.Count - 1)
                        {
                            moveList[ifml] = resignSymbol.ToString();
                            //urongMove = true;
                            unwantedMove = true;
                            //unwantedMoves = true;

                            //moveList[ifml] = urongMoveExample;
                        }
                    }
                    else
                    {
                        if (moveList[ifml - 1].IndexOf(checkmateSymbol) == -1)
                        {
                            if (ifml == moveList.Count - 1)
                                moveList[ifml] = resignSymbol.ToString();
                            else
                            {
                                moveList[ifml] = resignSymbol.ToString();
                                //urongMove = true;
                                unwantedMove = true;
                                //unwantedMoves = true;

                                //moveList[ifml] = urongMoveExample;
                            }
                        }
                        else
                        {
                            moveList.RemoveAt(ifml);
                            ifml--;
                        }
                    }
                }
            }

            #region Старо

            //if (moveList[moveList.Count - 1].IndexOf("/") != -1)
            //{
            //    //! =?= в режим CheckMoveList винаги е нов самостоятелен ход
            //    //! =S се дава винаги на най-скорошния ход
            //    //! =М се дава винаги на най-скорошния ход
            //    //! По-логично е (освен когато playerToMove дава + , за да се спаси с =FR) равенството да го поиска този, който е под шах, но работи и при +=FR със закоментиране на следващите 4+1(отдолу) реда

            //    if (moveList[moveList.Count - 2].IndexOf(checkSymbol) != -1)
            //        moveList[moveList.Count - 1] = drawSymbol.ToString();
            //    else
            //    {
            //        moveList[moveList.Count - 2] = string.Format("{0}{1}", moveList[moveList.Count - 2].Trim(), drawSymbol);
            //        moveList.RemoveAt(moveList.Count - 1);
            //    }
            //}

            //if (moveList[moveList.Count - 1].IndexOf("0") != -1) //! 0 (нула) вече има само в последния победен ход
            //{
            //    if ((moveList.Count == 1) || (moveList[moveList.Count - 2].IndexOf(checkmateSymbol) == -1))
            //        moveList[moveList.Count - 1] = resignSymbol.ToString();
            //    else if (moveList[moveList.Count - 2].IndexOf(checkmateSymbol) != -1) //! else if, тй като ако имаме единствен ход, ще хвърли изключение
            //        moveList.RemoveAt(moveList.Count - 1);
            //}

            #endregion

            using (StreamWriter makeReadyMoveList = new StreamWriter("readyMoveList.txt", false, Encoding.GetEncoding("windows-1251")))
            {
                makeReadyMoveList.Write(moveList[0].Trim());
                for (ifml = 1; ifml < moveList.Count; ifml++)
                    makeReadyMoveList.Write(string.Format("\r\n{0}", moveList[ifml].Trim()));
            }

            #region Старо

            //! Старото:
            //moveList.Clear();
            //using (StreamReader readReadyMoveList = new StreamReader("readyMoveList.txt", Encoding.GetEncoding("windows-1251")))
            //{
            //    string line;

            //    do
            //    {
            //        line = readReadyMoveList.ReadLine();
            //        if (line == null)
            //            break;

            //        moveList.Add(line);
            //    } while (true);
            //}

            #endregion

            return true;
        }

        #region Изключения

        catch (NullReferenceException)
        {
            Console.WriteLine("The move list file is empty!");
            return false;
        }
        catch (ArgumentNullException)
        {
            Console.WriteLine("The path to move list file is null!");
            return false;
        }
        catch (ArgumentException)
        {
            Console.WriteLine("The path to move list file is a zero-length string, contains only white space, or contains one or more invalid characters as defined by InvalidPathChars!");
            return false;
        }
        catch (PathTooLongException)
        {
            Console.WriteLine("The specified path to move list file, move list file, or both exceed the system-defined maximum length. For example, on Windows-based platforms, paths must be less than 248 characters, and file names must be less than 260 characters!");
            return false;
        }
        catch (FileNotFoundException)
        {
            Console.WriteLine("The to move list file specified in path was not found!");
            return false;
        }
        catch (DirectoryNotFoundException)
        {
            Console.WriteLine("The specified to move list file is invalid (for example, it is on an unmapped drive)!");
            return false;
        }
        catch (IOException)
        {
            Console.WriteLine("An I/O error occurred while opening a file!");
            return false;
        }
        catch (UnauthorizedAccessException)
        {
            Console.WriteLine("The path specified a file that is read-only.\n"
                            + "-or-\n"
                            + "This operation is not supported on the current platform.\n"
                            + "-or-\n"
                            + "path specified a directory.\n"
                            + "-or- \n"
                            + "The caller does not have the required permission!");
            return false;
        }
        catch (NotSupportedException)
        {
            Console.WriteLine("The path is in an invalid format!");
            return false;
        }
        catch (SecurityException)
        {
            Console.WriteLine("The caller does not have the required permission!");
            return false;
        }
        catch
        {
            Console.WriteLine("Fatal Error!");
            return false;
        }

        #endregion
    }

    #endregion

    #region Menu / Меню

    public static void MenuAtFirstPage()
    {
        switch (showHelpOrPlayTheGame())
        {
            case 1:
                {
                    playingSoundWhenStartingTheGame();
                    Play();
                    return; // for exit after first game
                }
            case 2:
                {
                    HelpMenu();
                    break;
                }
            default: break;
        }
    }

    public static void HelpMenu()
    {
        Console.BackgroundColor = menuBackgroundColor;
        Console.Clear();

        string things = "<   >";
        string numberOne = "1";
        string numberTwo = "2";
        string firtstPage = "Page 1";
        string secondPage = "Page 2";
        string startingGameMessage = "Press Enter for starting your game";
        string[] exampleFirstPage = new string[15]{
            "There are four types of game. To change, you must type the numbers from 0 to 3!",
            "- PC vs. PC (button '0')",
            "- Player vs. PC (button '1')",
            "- Player vs. Player (button '2')",
            "- Check move list (button '3')",
            "\n",
            "Show / Hide figures (blinfold) - button 'b'",
            "Stop / Start sound - button 's'",
            "\n",
            "There are three difficult levels - Amateur, Master, Nightmare.",
            "difficult Amateur - button 'a'",
            "difficult Master - button 'm'",
            "difficult Nightmare - button 'n'",
            "\n",
            "You can rotate the gaming table: 'r'(right), 'l'(left), 't'(top), 'd'(down)",};

        string[] exampleSecondPage = new string[18]{
            "Example: We have a4:b5 ",
            "\n",
            "a - the number of the column that current figure stays on",
            "It can be a, b, c, d, e, f, g, h.",
            "\n",
            "4 - the number of the row that current figure stays on",
            "It can be 1, 2, 3, 4, 5, 6, 7, 8.",
            "\n",
            "':' means that we will get a figure ('x' can also be used).",
            "The enemy's figure that we will get stays on b5.",
            "a4:b5 will move our figure to column 'b' and row 5 and will get",
            "the enemy's figure.",
            "\n",
            "If you want to earn a new figure you must write '=' and the figure you want.", 
            "'=' without special figure after it means that you give a stalemate.", 
            "\n",
            "If you want to give a check you must write '+'. ",
            "For checkmate you must write '#'." };

        //First page
        Console.ForegroundColor = menuForegroundColorWhileNotChosen;
        Console.SetCursorPosition(74, 1);
        Console.WriteLine(firtstPage);
        Console.ForegroundColor = menuForegroundColorForCurrentMainText;
        Console.SetCursorPosition(61, 28);
        Console.WriteLine(startingGameMessage);
        Console.ForegroundColor = menuForegroundColorWhileNotChosen;
        Console.SetCursorPosition(75, 30);
        Console.WriteLine(things);
        Console.SetCursorPosition(76, 30);
        Console.ForegroundColor = menuForegroundColorWhileChosen;
        Console.WriteLine(numberOne);
        Console.SetCursorPosition(78, 30);
        Console.ForegroundColor = menuForegroundColorWhileNotChosen;
        Console.WriteLine(numberTwo);

        Console.ForegroundColor = menuForegroundColorWhileChosen;
        for (int i = 0; i < exampleFirstPage.Length; i++)
        {
            Console.SetCursorPosition(77 - exampleFirstPage[i].Length / 2, i + 3);
            Console.WriteLine(exampleFirstPage[i]);
        }

        int counter = 1;
        ConsoleKeyInfo keyInfo;
        while ((keyInfo = Console.ReadKey(true)).Key != ConsoleKey.Escape)
        {
            switch (keyInfo.Key)
            {
                case ConsoleKey.Enter:
                    do
                    {
                        playingSoundWhenStartingTheGame();
                        Play();
                    } while (true);
                case ConsoleKey.LeftArrow:
                    playingSoundWhenPressingButton();
                    counter--;
                    break;
                case ConsoleKey.RightArrow:
                    playingSoundWhenPressingButton();
                    counter++;
                    break;
            }

            if (counter == 3)
                counter = 1;

            if (counter == 0)
                counter = 2;

            if (counter == 1)
            {
                Console.Clear();
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.SetCursorPosition(74, 1);
                Console.WriteLine(firtstPage);
                Console.ForegroundColor = menuForegroundColorForCurrentMainText;
                Console.SetCursorPosition(61, 28);
                Console.WriteLine(startingGameMessage);
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.SetCursorPosition(75, 30);
                Console.WriteLine(things);
                Console.SetCursorPosition(76, 30);
                Console.ForegroundColor = menuForegroundColorWhileChosen;
                Console.WriteLine(numberOne);
                Console.SetCursorPosition(78, 30);
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.WriteLine(numberTwo);

                Console.ForegroundColor = menuForegroundColorWhileChosen;
                for (int i = 0; i < exampleFirstPage.Length; i++)
                {
                    Console.SetCursorPosition(77 - exampleFirstPage[i].Length / 2, i + 3);
                    Console.WriteLine(exampleFirstPage[i]);
                }
            }

            if (counter == 2)
            {
                Console.Clear();
                Console.SetCursorPosition(74, 1);
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.WriteLine(secondPage);
                Console.ForegroundColor = menuForegroundColorForCurrentMainText;
                Console.SetCursorPosition(61, 28);
                Console.WriteLine(startingGameMessage);
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.SetCursorPosition(75, 30);
                Console.WriteLine(things);
                Console.SetCursorPosition(76, 30);
                Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                Console.WriteLine(numberOne);
                Console.SetCursorPosition(78, 30);
                Console.ForegroundColor = menuForegroundColorWhileChosen;
                Console.WriteLine(numberTwo);

                Console.ForegroundColor = menuForegroundColorWhileChosen;
                for (int i = 0; i < exampleSecondPage.Length; i++)
                {
                    Console.SetCursorPosition(77 - exampleSecondPage[i].Length / 2, i + 3);
                    Console.WriteLine(exampleSecondPage[i]);
                }
            }
        }
    }

    public static void PrintingOuterFrame()
    {
        Console.SetWindowSize(155, 32);
        Console.Clear();
        Console.SetBufferSize(Console.WindowWidth, 32);
        string outerEmptyByVertical = new string(' ', 3);
        string outerEmptyByHorizontal = new string(' ', Console.BufferWidth);
        string outerEmptyByHorizontalAnotherColor = new string(' ', Console.BufferWidth - 6);
        for (int i = 0; i < Console.BufferHeight - 1; i++)
        {
            Console.BackgroundColor = menuColorOfOuterFrameBackgroundMenu;
            Console.ForegroundColor = menuColorOfOuterFrameForegroundMenu;
            Console.SetCursorPosition(0, i);
            Console.WriteLine(outerEmptyByVertical);
            Console.SetCursorPosition(Console.BufferWidth - 3, i);
            Console.WriteLine(outerEmptyByVertical);
        }

        for (int i = 0; i < 2; i++)
        {
            Console.BackgroundColor = menuColorOfOuterFrameBackgroundMenu;
            Console.ForegroundColor = menuColorOfOuterFrameForegroundMenu;
            Console.SetCursorPosition(3, i);
            Console.WriteLine(outerEmptyByHorizontal);
        }

        Console.SetCursorPosition(3, 3);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(3, 5);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(3, 2);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(3, 28);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(3, 30);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(0, 30);
        Console.WriteLine(outerEmptyByVertical);
        Console.SetCursorPosition(151, 30);
        Console.WriteLine(outerEmptyByVertical);
        Console.BackgroundColor = menuColorForPrinting;
        Console.ForegroundColor = menuColorOfOuterFrameForegroundMenu;
        Console.SetCursorPosition(3, 2);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
        Console.SetCursorPosition(3, 29);
        Console.WriteLine(outerEmptyByHorizontalAnotherColor);
    }

    public static int showHelpOrPlayTheGame()
    {
        Console.SetBufferSize(155, 32);
        Console.CursorVisible = false;
        PrintingOuterFrame();
        string firstText = "Start the game";
        string secondText = "How To Play?";

        Console.BackgroundColor = menuBackgroundColor;
        Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2 - 2);
        Console.ForegroundColor = menuForegroundColorWhileChosen;
        Console.WriteLine(firstText);
        Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2);
        Console.ForegroundColor = menuForegroundColorWhileNotChosen;
        Console.WriteLine(secondText);

        int startGameOrShowHelp = 1;
        ConsoleKeyInfo keyInfo;
        while ((keyInfo = Console.ReadKey(true)).Key != ConsoleKey.Escape)
        {
            switch (keyInfo.Key)
            {
                case ConsoleKey.Enter:
                    playingSoundWhenPressingButton();
                    return startGameOrShowHelp;
                case ConsoleKey.UpArrow:
                    playingSoundWhenPressingButton();
                    startGameOrShowHelp--;
                    break;

                case ConsoleKey.DownArrow:
                    playingSoundWhenPressingButton();
                    startGameOrShowHelp++;
                    break;
            }

            switch (startGameOrShowHelp)
            {
                case 1:
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2 - 2);
                    Console.ForegroundColor = menuForegroundColorWhileChosen;
                    Console.WriteLine(firstText);
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2);
                    Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                    Console.WriteLine(secondText);
                    break;
                case 2:
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2 - 2);
                    Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                    Console.WriteLine(firstText);
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2);
                    Console.ForegroundColor = menuForegroundColorWhileChosen;
                    Console.WriteLine(secondText);
                    break;
                case 0:
                    startGameOrShowHelp = 2;
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2 - 2);
                    Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                    Console.WriteLine(firstText);
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2);
                    Console.ForegroundColor = menuForegroundColorWhileChosen;
                    Console.WriteLine(secondText);
                    break;
                case 3:
                    startGameOrShowHelp = 1;
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2 - 2);
                    Console.ForegroundColor = menuForegroundColorWhileChosen;
                    Console.WriteLine(firstText);
                    Console.SetCursorPosition(Console.BufferWidth / 3 + 19, Console.BufferHeight / 2);
                    Console.ForegroundColor = menuForegroundColorWhileNotChosen;
                    Console.WriteLine(secondText);
                    break;
                default:
                    break;
            }
        }
        return startGameOrShowHelp;
    }

    public static void playingSoundWhenPressingButton()
    {
        using (SoundPlayer player = new SoundPlayer(@"../../step.wav"))
        {
            player.Play();
        }
    }

    public static void playingSoundWhenStartingTheGame()
    {
        using (SoundPlayer player = new SoundPlayer(@"../../start.wav"))
        {
            player.Play();
        }
    }

    #endregion

    #region Print / Визуализация

    public static void FullPrint() // Пълна картина на игралната маса и списъка с ходовете 
    {
        Console.CursorVisible = false;
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Clear();

        PrintBattlefield(lookingAngles[playerToMove]);
        PrintLastMoves();
    }

    public static void PrintBattlefield(int angleOfLooking) // Игрална маса 
    {
        if (blindfold)
        {
            Console.CursorVisible = false;
            Console.SetCursorPosition(0, 0);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.ForegroundColor = colorOfOuterFrameForeground;
            Console.WriteLine(outerHorizontalEmpty);
            Console.WriteLine(outerHorizontalTextLine[angleOfLooking]);
            Console.WriteLine(outerHorizontalEmpty);
            Console.Write(outerEmptyByVertical);
            Console.BackgroundColor = colorOfInternalFrame;
            Console.Write(internalHorizontalEmpty);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.WriteLine(outerEmptyByVertical);

            for (pbi = 7; pbi >= 0; pbi--)
            {
                switch (angleOfLooking)
                {
                    case 0: { outerHorizontalSymbolByVertical = pbi + 49;   break; }
                    case 1: { outerHorizontalSymbolByVertical = 104 - pbi;  break; }
                    case 2: { outerHorizontalSymbolByVertical = 56 - pbi;   break; }
                    case 3: { outerHorizontalSymbolByVertical = pbi + 97;   break; }
                    default: break;
                }

                for (pbk = 0; pbk <= 2; pbk++)
                {
                    Console.BackgroundColor = colorOfOuterFrameBackground;
                    Console.ForegroundColor = colorOfOuterFrameForeground;
                    Console.Write(" {0} ", pbk == 1 ? (char)outerHorizontalSymbolByVertical : ' ');
                    Console.BackgroundColor = colorOfInternalFrame;
                    Console.Write(" ");

                    for (pbj = 0; pbj <= 7; pbj++)
                    {
                        if ((pbi + pbj + angleOfLooking + 1) % 2 == 0)
                            Console.BackgroundColor = colorOfWhiteFields;
                        else
                            Console.BackgroundColor = colorOfBlackFields;

                        Console.Write(fieldEmptyByHorizontal);
                    }

                    Console.BackgroundColor = colorOfInternalFrame;
                    Console.Write(" ");
                    Console.BackgroundColor = colorOfOuterFrameBackground;
                    Console.ForegroundColor = colorOfOuterFrameForeground;
                    Console.WriteLine(" {0} ", pbk == 1 ? (char)outerHorizontalSymbolByVertical : ' ');
                }
            }

            Console.Write(outerEmptyByVertical);
            Console.BackgroundColor = colorOfInternalFrame;
            Console.Write(internalHorizontalEmpty);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.WriteLine(outerEmptyByVertical);
            Console.WriteLine(outerHorizontalEmpty);
            Console.WriteLine(outerHorizontalTextLine[angleOfLooking]);
            Console.Write(outerHorizontalEmpty);
        }
        else
        {
            switch (angleOfLooking)
            {
                case 0: { nextTakenFigure[0] = 0; nextTakenFigure[1] = 15; break; }
                case 1: { nextTakenFigure[0] = 15; nextTakenFigure[1] = 0; break; }
                case 2: { nextTakenFigure[0] = 15; nextTakenFigure[1] = 0; break; }
                case 3: { nextTakenFigure[0] = 0; nextTakenFigure[1] = 15; break; }
                default: break;
            }

            Console.CursorVisible = false;
            Console.SetCursorPosition(0, 0);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.ForegroundColor = colorOfOuterFrameForeground;
            Console.Write(outerHorizontalEmptyEnds);

            switch (angleOfLooking)
            {
                case 1:
                    {
                        for (pbi = 0; pbi < 40; pbi++)
                        {
                            if ((pbi % 5 != 1) && (pbi % 5 != 3))
                                Console.Write(" ");
                            else
                            {
                                if (nextTakenFigure[0] < takenFigures[0].Count)
                                {
                                    Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                    Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                    Console.Write(TakenFigure(takenFigures[0][nextTakenFigure[0]]));
                                    Console.BackgroundColor = colorOfOuterFrameBackground;
                                    Console.ForegroundColor = colorOfOuterFrameForeground;
                                }
                                else
                                    Console.Write(" ");

                                nextTakenFigure[0]--;
                            }
                        }

                        break;
                    }
                case 3:
                    {
                        for (pbi = 0; pbi < 40; pbi++)
                        {
                            if ((pbi % 5 != 1) && (pbi % 5 != 3))
                                Console.Write(" ");
                            else
                            {
                                if (nextTakenFigure[1] < takenFigures[1].Count)
                                {
                                    Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                    Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                    Console.Write(TakenFigure(takenFigures[1][nextTakenFigure[1]]));
                                    Console.BackgroundColor = colorOfOuterFrameBackground;
                                    Console.ForegroundColor = colorOfOuterFrameForeground;
                                }
                                else
                                    Console.Write(" ");

                                nextTakenFigure[1]--;
                            }
                        }

                        break;
                    }
                default: { Console.Write(outerHorizontalEmptyMiddle); break; }
            }

            Console.WriteLine(outerHorizontalEmptyEnds);
            Console.WriteLine(outerHorizontalTextLine[angleOfLooking]);
            Console.WriteLine(outerHorizontalEmpty);
            Console.Write(outerEmptyByVertical);
            Console.BackgroundColor = colorOfInternalFrame;
            Console.Write(internalHorizontalEmpty);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.WriteLine(outerEmptyByVertical);

            for (pbi = 7; pbi >= 0; pbi--)
            {
                switch (angleOfLooking)
                {
                    case 0: { outerHorizontalSymbolByVertical = pbi + 49;   break; }
                    case 1: { outerHorizontalSymbolByVertical = 104 - pbi;  break; }
                    case 2: { outerHorizontalSymbolByVertical = 56 - pbi;   break; }
                    case 3: { outerHorizontalSymbolByVertical = pbi + 97;   break; }
                    default: break;
                }

                for (pbk = 0; pbk <= 2; pbk++)
                {
                    Console.BackgroundColor = colorOfOuterFrameBackground;
                    Console.ForegroundColor = colorOfOuterFrameForeground;

                    if (pbk == 1)
                        Console.Write(" ");
                    else
                    {
                        switch (angleOfLooking)
                        {
                            case 0:
                                {
                                    if (nextTakenFigure[0] < takenFigures[0].Count)
                                    {
                                        Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                        Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                        Console.Write(TakenFigure(takenFigures[0][nextTakenFigure[0]]));
                                        Console.BackgroundColor = colorOfOuterFrameBackground;
                                        Console.ForegroundColor = colorOfOuterFrameForeground;
                                    }
                                    else
                                        Console.Write(" ");

                                    nextTakenFigure[0]++;
                                    break;
                                }
                            case 2:
                                {
                                    if (nextTakenFigure[1] < takenFigures[1].Count)
                                    {
                                        Console.BackgroundColor = colorOfTakensBlackFigureBackground;
                                        Console.ForegroundColor = colorOfTakensBlackFigureForeground;
                                        Console.Write(TakenFigure(takenFigures[1][nextTakenFigure[1]]));
                                        Console.BackgroundColor = colorOfOuterFrameBackground;
                                        Console.ForegroundColor = colorOfOuterFrameForeground;
                                    }
                                    else
                                        Console.Write(" ");

                                    nextTakenFigure[1]++;
                                    break;
                                }
                            default: { Console.Write(" "); break; }
                        }
                    }

                    Console.Write("{0} ", pbk == 1 ? (char)outerHorizontalSymbolByVertical : ' ');
                    Console.BackgroundColor = colorOfInternalFrame;
                    Console.Write(" ");

                    for (pbj = 0; pbj <= 7; pbj++)
                    {
                        switch (angleOfLooking)
                        {
                            case 0: { figureInField = battlefield[pbi, pbj];            break; }
                            case 1: { figureInField = battlefield[pbj, 7 - pbi];        break; }
                            case 2: { figureInField = battlefield[7 - pbi, 7 - pbj];    break; }
                            case 3: { figureInField = battlefield[7 - pbj, pbi];        break; }
                            default: break;
                        }

                        if ((pbi + pbj + angleOfLooking + 1) % 2 == 0)
                            Console.BackgroundColor = colorOfWhiteFields;
                        else
                            Console.BackgroundColor = colorOfBlackFields;

                        if (pbk == 1)
                            Console.Write("  {0}  ", Figure(figureInField));
                        else
                            Console.Write(fieldEmptyByHorizontal);
                    }

                    Console.BackgroundColor = colorOfInternalFrame;
                    Console.Write(" ");
                    Console.BackgroundColor = colorOfOuterFrameBackground;
                    Console.ForegroundColor = colorOfOuterFrameForeground;
                    Console.Write(" {0}", pbk == 1 ? (char)outerHorizontalSymbolByVertical : ' ');

                    if (pbk == 1)
                        Console.WriteLine(" ");
                    else
                    {
                        switch (angleOfLooking)
                        {
                            case 0:
                                {
                                    if (nextTakenFigure[1] < takenFigures[1].Count)
                                    {
                                        Console.BackgroundColor = colorOfTakensBlackFigureBackground;
                                        Console.ForegroundColor = colorOfTakensBlackFigureForeground;
                                        Console.WriteLine(TakenFigure(takenFigures[1][nextTakenFigure[1]]));
                                        Console.BackgroundColor = colorOfOuterFrameBackground;
                                        Console.ForegroundColor = colorOfOuterFrameForeground;
                                    }
                                    else
                                        Console.WriteLine(" ");

                                    nextTakenFigure[1]--;
                                    break;
                                }
                            case 2:
                                {
                                    if (nextTakenFigure[0] < takenFigures[0].Count)
                                    {
                                        Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                        Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                        Console.WriteLine(TakenFigure(takenFigures[0][nextTakenFigure[0]]));
                                        Console.BackgroundColor = colorOfOuterFrameBackground;
                                        Console.ForegroundColor = colorOfOuterFrameForeground;
                                    }
                                    else
                                        Console.WriteLine(" ");

                                    nextTakenFigure[0]--;
                                    break;
                                }
                            default: { Console.WriteLine(" "); break; }
                        }
                    }
                }
            }

            Console.Write(outerEmptyByVertical);
            Console.BackgroundColor = colorOfInternalFrame;
            Console.Write(internalHorizontalEmpty);
            Console.BackgroundColor = colorOfOuterFrameBackground;
            Console.WriteLine(outerEmptyByVertical);
            Console.WriteLine(outerHorizontalEmpty);
            Console.WriteLine(outerHorizontalTextLine[angleOfLooking]);
            Console.Write(outerHorizontalEmptyEnds);

            switch (angleOfLooking)
            {
                case 1:
                    {
                        for (pbi = 0; pbi < 40; pbi++)
                        {
                            if ((pbi % 5 != 1) && (pbi % 5 != 3))
                                Console.Write(" ");
                            else
                            {
                                if (nextTakenFigure[1] < takenFigures[1].Count)
                                {
                                    Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                    Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                    Console.Write(TakenFigure(takenFigures[1][nextTakenFigure[1]]));
                                    Console.BackgroundColor = colorOfOuterFrameBackground;
                                    Console.ForegroundColor = colorOfOuterFrameForeground;
                                }
                                else
                                    Console.Write(" ");

                                nextTakenFigure[1]++;
                            }
                        }

                        break;
                    }
                case 3:
                    {
                        for (pbi = 0; pbi < 40; pbi++)
                        {
                            if ((pbi % 5 != 1) && (pbi % 5 != 3))
                                Console.Write(" ");
                            else
                            {
                                if (nextTakenFigure[0] < takenFigures[0].Count)
                                {
                                    Console.BackgroundColor = colorOfTakensWhiteFigureBackground;
                                    Console.ForegroundColor = colorOfTakensWhiteFigureForeground;
                                    Console.Write(TakenFigure(takenFigures[0][nextTakenFigure[0]]));
                                    Console.BackgroundColor = colorOfOuterFrameBackground;
                                    Console.ForegroundColor = colorOfOuterFrameForeground;
                                }
                                else
                                    Console.Write(" ");

                                nextTakenFigure[0]++;
                            }
                        }

                        break;
                    }
                default: { Console.Write(outerHorizontalEmptyMiddle); break; }
            }

            Console.Write(outerHorizontalEmptyEnds);
        }
    }

    public static char Figure(int field) // Фигура на полето 
    {
        if ((figures[0][0][0] - kingUnits < field) && (field <= figures[0][0][0]))
            Console.ForegroundColor = colorOfWhiteFigures;
        else
            Console.ForegroundColor = colorOfBlackFigures;

        switch (field % 10)
        {
            case emptyField:    return ' ';
            case pawnUnits:     return 'p';
            case nightUnits:    return 'N';
            case bishopUnits:   return 'B';
            case rookUnits:     return 'R';
            case queenUnits:    return 'Q';
            case kingUnits:     return 'K';
            default:            return ' ';
        }
    }

    public static char TakenFigure(int field) // Взета фигура 
    {
        if ((figures[0][0][0] - kingUnits < field) && (field <= figures[0][0][0]))
            Console.ForegroundColor = colorOfWhiteFigures;
        else
            Console.ForegroundColor = colorOfBlackFigures;

        switch (field % 10)
        {
            case emptyField:    return ' ';
            case pawnUnits:     return 'p';
            case nightUnits:    return 'N';
            case bishopUnits:   return 'B';
            case rookUnits:     return 'R';
            case queenUnits:    return 'Q';
            case kingUnits:     return 'K';
            default:            return ' ';
        }
    }

    public static void PrintLastMoves(bool makesClean = false) // Списък с изиграните ходове (и току що изпробвания) 
    {
        if (makesClean)
            ClearMovesBlackboard();

        #region Top and bottom lines

            #region Top

        Console.BackgroundColor = colorOfTopHelpBackground;
        Console.ForegroundColor = colorOfTopHelpForeground;
        Console.SetCursorPosition(49, 0);

        Console.Write(topHelp);

            #endregion

            #region Bottom

        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.SetCursorPosition(49, 31);

        //Console.Write("  Mode");
        Console.Write(" ");
        for (plmbl = 0; plmbl < gameModes.Count; plmbl++)
            if (gameMode == (GameModes)plmbl)
            {
                Console.BackgroundColor = colorOfBottomHelpBackground;
                Console.ForegroundColor = colorOfBottomHelpForeground;
                Console.Write(" {0}", gameModes[plmbl]);
                Console.BackgroundColor = colorOfDefaultBackground;
                Console.ForegroundColor = colorOfDefaultForeground;
            }
            else
                Console.Write(" {0}", gameModes[plmbl]);

        Console.Write(" pie");
        Console.BackgroundColor = colorOfBottomHelpBackground;
        Console.ForegroundColor = colorOfBottomHelpForeground;
        Console.Write("C");
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Write("es ");

        Console.BackgroundColor = colorOfBottomHelpBackground;
        Console.ForegroundColor = colorOfBottomHelpForeground;
        Console.Write("B");
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Write("lindfold ");

        Console.BackgroundColor = colorOfBottomHelpBackground;
        Console.ForegroundColor = colorOfBottomHelpForeground;
        Console.Write("S");
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Write("ound ");

        Console.BackgroundColor = colorOfBottomHelpBackground;
        Console.ForegroundColor = colorOfBottomHelpForeground;
        Console.Write("DLR");
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Write("o");
        Console.BackgroundColor = colorOfBottomHelpBackground;
        Console.ForegroundColor = colorOfBottomHelpForeground;
        Console.Write("T");
        Console.BackgroundColor = colorOfDefaultBackground;
        Console.ForegroundColor = colorOfDefaultForeground;
        Console.Write("ation");

        Console.BackgroundColor = colorOfSetsBackground;
        Console.ForegroundColor = colorOfSetsForeground;
        Console.Write(" {0}", sets);
        Console.BackgroundColor = colorOfTheEndingDrawMoveBackground;
        Console.ForegroundColor = colorOfTheEndingDrawMoveForeground;
        Console.Write(" ={0}", draws);
        Console.BackgroundColor = colorOfTheEndingCheckmateMoveBackground;
        Console.ForegroundColor = colorOfTheEndingCheckmateMoveForeground;
        Console.Write(" #{0}+{1}", wins[0], wins[1]);
        Console.BackgroundColor = colorOfTheEndingResignMoveBackground;
        Console.ForegroundColor = colorOfTheEndingResignMoveForeground;
        Console.Write(" .{0}+{1}", resigns[0], resigns[1]);
        Console.BackgroundColor = colorOfGameDifficultyBackground;
        Console.ForegroundColor = colorOfGameDifficultyForeground;
        Console.Write(" {1}-{2}", gameDifficulties[(int)gameDifficulty], gameDifficulties[(int)gameBothDifficulty[0]], gameDifficulties[(int)gameBothDifficulty[1]]);
        Console.BackgroundColor = colorOfTimersBackground;
        Console.ForegroundColor = colorOfTimersForeground;
        Console.Write(" {1}", oldSets - sets, duration);
        Console.BackgroundColor = colorOfTotalSpeedBackground;
        Console.ForegroundColor = colorOfTotalSpeedForeground;
        Console.Write(" {0:0,#}", totalSpeed);
        Console.BackgroundColor = colorOfMovesBackground;
        Console.ForegroundColor = colorOfMovesForeground;
        Console.Write(" {0:n0}", (int)((totalSpeed * 1000) / (int)duration.TotalMilliseconds));

            #endregion

        #region Bottom --- Star variant

        //Console.BackgroundColor = colorOfTopHelpBackground;
        //Console.ForegroundColor = colorOfTopHelpForeground;
        //Console.SetCursorPosition(49, 0);
        //Console.Write(topHelp);
        //Console.BackgroundColor = colorOfBottomHelpBackground;
        //Console.ForegroundColor = colorOfBottomHelpForeground;
        //Console.SetCursorPosition(49, 31);
        //Console.Write("Mode");
        //Console.BackgroundColor = colorOfGameModeBackground;
        //Console.ForegroundColor = colorOfGameModeForeground;
        //Console.Write(" {0}", gameModes[(int)gameMode]);
        //Console.BackgroundColor = colorOfBottomHelpBackground;
        //Console.ForegroundColor = colorOfBottomHelpForeground;
        //Console.Write(" {0}", bottomHelp);
        //Console.BackgroundColor = colorOfSetsBackground;
        //Console.ForegroundColor = colorOfSetsForeground;
        //Console.Write(" {0}", sets);
        //Console.BackgroundColor = colorOfTheEndingDrawMoveBackground;
        //Console.ForegroundColor = colorOfTheEndingDrawMoveForeground;
        //Console.Write(" ={0}", draws);
        //Console.BackgroundColor = colorOfTheEndingCheckmateMoveBackground;
        //Console.ForegroundColor = colorOfTheEndingCheckmateMoveForeground;
        //Console.Write(" #{0}+{1}", wins[0], wins[1]);
        //Console.BackgroundColor = colorOfTheEndingResignMoveBackground;
        //Console.ForegroundColor = colorOfTheEndingResignMoveForeground;
        //Console.Write(" .{0}+{1}", resigns[0], resigns[1]);
        //Console.BackgroundColor = colorOfGameDifficultyBackground;
        //Console.ForegroundColor = colorOfGameDifficultyForeground;
        //Console.Write(" {1}-{2}", gameDifficulties[(int)gameDifficulty], gameDifficulties[(int)gameBothDifficulty[0]], gameDifficulties[(int)gameBothDifficulty[1]]);
        //Console.BackgroundColor = colorOfTimersBackground;
        //Console.ForegroundColor = colorOfTimersForeground;
        //Console.Write(" {1}", oldSets - sets, duration);
        //Console.BackgroundColor = colorOfTotalSpeedBackground;
        //Console.ForegroundColor = colorOfTotalSpeedForeground;
        //Console.Write(" {0}", totalSpeed);
        //Console.BackgroundColor = colorOfMovesBackground;
        //Console.ForegroundColor = colorOfMovesForeground;

        #endregion

        #endregion

        #region Moves

        nextWhiteToMove = 0;

        // if numbers and moves are same formated
        //Console.BackgroundColor = colorOfMovesBackground;
        //Console.ForegroundColor = colorOfMovesForeground;

        if (0 < lastMoves[0].Count)
        {
            if ((lastMoves[0].Count < 120)
                || ((lastMoves[0].Count == 120) && (lastMoves[1].Count == 119))
                    || ((lastMoves[0].Count == 120) && (lastMoves[1].Count == 120) && ((realState != States.Free) && (realState != States.Check))))
            {
                for (plm = 0; plm < lastMoves[0].Count; plm++)
                {
                    nextWhiteToMove = plm + 1;
                    Console.SetCursorPosition(49 + (plm / 30) * 23, 1 + (plm % 30));

                    // if numbers and moves are same formated
                    if ((plm == lastMoves[0].Count - 1) && ((lastMoves[1].Count < lastMoves[0].Count) || ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign)))
                            || ((gameMode == GameModes.CheckMoveList) && ((currentMove == 2 * plm + 1) || (currentMove == 2 * plm + 2))))
                    {
                        if (realState == States.Draw)
                        {
                            Console.BackgroundColor = colorOfTheEndingDrawMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingDrawMoveForeground;
                        }
                        else if (realState == States.Checkmate)
                        {
                            Console.BackgroundColor = colorOfTheEndingCheckmateMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingCheckmateMoveForeground;
                        }
                        else if (realState == States.Resign)
                        {
                            Console.BackgroundColor = colorOfTheEndingResignMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingResignMoveForeground;
                        }
                        else
                        {
                            Console.BackgroundColor = colorOfNewNumberOfMovesBackground;
                            Console.ForegroundColor = colorOfNewNumberOfMovesForeground;
                        }
                    }
                    else
                    {
                        Console.BackgroundColor = colorOfNumbersOfMovesBackground;
                        Console.ForegroundColor = colorOfNumbersOfMovesForeground;
                    }

                    if (plm < 90)
                        Console.Write("{0,2}. ", (plm + 1));
                    else
                        Console.Write("{0,3}. ", (plm + 1));

                    Console.BackgroundColor = colorOfMovesBackground;
                    Console.ForegroundColor = colorOfMovesForeground;

                    // the change in comparison with next comment is from here to it

                    if (plm < lastMoves[0].Count - 1)
                    {
                        Console.Write("{0,-9}", lastMoves[0][plm]);
                        if (plm < lastMoves[1].Count)
                            Console.Write("{0}", lastMoves[1][plm]);
                    }
                    else
                    {
                        if ((realState == States.Free) || (realState == States.Check))
                        {
                            Console.Write("{0,-9}", lastMoves[0][plm]);
                            if (plm < lastMoves[1].Count)
                                Console.Write("{0}", lastMoves[1][plm]);
                        }
                        else
                        {
                            if (lastMoves[1].Count < lastMoves[0].Count)
                            {
                                PreparingForPrintOfTheEndingMove();
                                Console.Write("{0,-9}", lastMoves[0][plm]);
                            }
                            else
                            {
                                Console.Write("{0,-9}", lastMoves[0][plm]);
                                PreparingForPrintOfTheEndingMove();
                                Console.Write("{0}", lastMoves[1][plm]);
                            }
                        }
                    }

                    //Console.Write("{0, -11}", lastMoves[0][plmi]);
                    //if (plmi < lastMoves[1].Count)
                    //    Console.Write("{0}", lastMoves[1][plmi]);
                }

                if (gameMode != GameModes.CheckMoveList)
                    Console.CursorVisible = true;

                // add condition and for realState
                if ((gameMode != GameModes.CheckMoveList) && (lastMoves[0].Count == lastMoves[1].Count) 
                        && ((realState == States.Free) || (realState == States.Check)))
                {
                    Console.SetCursorPosition(49 + (nextWhiteToMove / 30) * 23, 1 + (nextWhiteToMove % 30));
                    Console.BackgroundColor = colorOfNewNumberOfMovesBackground;
                    Console.ForegroundColor = colorOfNewNumberOfMovesForeground;

                    if (nextWhiteToMove < 90)
                        Console.Write("{0,2}. ", nextWhiteToMove + 1);
                    else
                        Console.Write("{0,3}. ", nextWhiteToMove + 1);

                    Console.BackgroundColor = colorOfMovesBackground;
                    Console.ForegroundColor = colorOfMovesForeground;
                    Console.CursorVisible = true;
                }
            }
            else
            {
                mov = lastMoves[0].Count;
                colon = 0;

                for (plm = mov - mov % 30 - 90 - (mov % 30 == 0 ? 30 : 0); plm < lastMoves[0].Count; plm++) // - (mov % 30 == 0 ? 30 : 0)
                {
                    nextWhiteToMove = colon + 1;
                    Console.SetCursorPosition(49 + (colon / 30) * 23, 1 + (plm % 30));
                    colon++;

                    // if numbers and moves are same formated
                    if ((plm == lastMoves[0].Count - 1) && ((lastMoves[1].Count < lastMoves[0].Count) || ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign)))
                            || ((gameMode == GameModes.CheckMoveList) && ((currentMove == 2 * plm + 1) || (currentMove == 2 * plm + 2))))
                    {
                        if (realState == States.Draw)
                        {
                            Console.BackgroundColor = colorOfTheEndingDrawMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingDrawMoveForeground;
                        }
                        else if (realState == States.Checkmate)
                        {
                            Console.BackgroundColor = colorOfTheEndingCheckmateMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingCheckmateMoveForeground;
                        }
                        else if (realState == States.Resign)
                        {
                            Console.BackgroundColor = colorOfTheEndingResignMoveBackground;
                            Console.ForegroundColor = colorOfTheEndingResignMoveForeground;
                        }
                        else
                        {
                            Console.BackgroundColor = colorOfNewNumberOfMovesBackground;
                            Console.ForegroundColor = colorOfNewNumberOfMovesForeground;
                        }
                    }
                    else
                    {
                        Console.BackgroundColor = colorOfNumbersOfMovesBackground;
                        Console.ForegroundColor = colorOfNumbersOfMovesForeground;
                    }

                    if (plm < 90)
                        Console.Write("{0,2}. ", (plm + 1));
                    else
                        Console.Write("{0,3}. ", (plm + 1));

                    // if numbers and moves are same formated
                    Console.BackgroundColor = colorOfMovesBackground;
                    Console.ForegroundColor = colorOfMovesForeground;

                    if (plm < lastMoves[0].Count - 1)
                    {
                        Console.Write("{0,-9}", lastMoves[0][plm]);
                        if (plm < lastMoves[1].Count)
                            Console.Write("{0}", lastMoves[1][plm]);
                    }
                    else
                    {
                        if ((realState == States.Free) || (realState == States.Check))
                        {
                            Console.Write("{0,-9}", lastMoves[0][plm]);
                            if (plm < lastMoves[1].Count)
                                Console.Write("{0}", lastMoves[1][plm]);
                        }
                        else
                        {
                            if (lastMoves[1].Count < lastMoves[0].Count)
                            {
                                PreparingForPrintOfTheEndingMove();
                                Console.Write("{0,-9}", lastMoves[0][plm]);
                            }
                            else
                            {
                                Console.Write("{0,-9}", lastMoves[0][plm]);
                                PreparingForPrintOfTheEndingMove();
                                Console.Write("{0}", lastMoves[1][plm]);
                            }
                        }
                    }
                }

                if (gameMode != GameModes.CheckMoveList)
                    Console.CursorVisible = true;

                if ((gameMode != GameModes.CheckMoveList) && (lastMoves[0].Count == lastMoves[1].Count) && ((realState == States.Free) || (realState == States.Check)))
                {
                    Console.SetCursorPosition(49 + (colon / 30) * 23, 1 + (plm % 30));
                    Console.BackgroundColor = colorOfNewNumberOfMovesBackground;
                    Console.ForegroundColor = colorOfNewNumberOfMovesForeground;

                    if (plm < 90)
                        Console.Write("{0,2}. ", plm + 1);
                    else
                        Console.Write("{0,3}. ", plm + 1);

                    Console.BackgroundColor = colorOfMovesBackground;
                    Console.ForegroundColor = colorOfMovesForeground;
                    Console.CursorVisible = true;
                }

                // instead of upper one
                //if ((gameMode != GameModes.CheckMoveList) && (lastMoves[0].Count == lastMoves[1].Count) && ((realState == States.Free) || (realState == States.Check)))
                //{
                //    Console.SetCursorPosition(49 + (nextWhiteToMove / 30) * 26, 1 + (nextWhiteToMove % 30));

                //    if (nextWhiteToMove < 90)
                //        Console.Write("{0,2}. ", nextWhiteToMove + 1);
                //    else
                //        Console.Write("{0,3}. ", nextWhiteToMove + 1);

                //    Console.CursorVisible = true;
                //}
            }
        }
        else
        {
            if (gameMode != GameModes.CheckMoveList)
            {
                Console.SetCursorPosition(49, 1);

                if ((gameMode == GameModes.PlayerVsComputer || gameMode == GameModes.FinishGame) && (playWith == 0) && printBeforeFirstMove)
                {
                    Console.BackgroundColor = colorOfFirstMoveBackground;
                    Console.ForegroundColor = colorOfFirstMoveForeground;
                }
                else
                {
                    Console.BackgroundColor = colorOfNewNumberOfMovesBackground;
                    Console.ForegroundColor = colorOfNewNumberOfMovesForeground;
                }

                Console.Write("{0,2}. ", (1));
                Console.BackgroundColor = colorOfMovesBackground;
                Console.ForegroundColor = colorOfMovesForeground;
                Console.CursorVisible = true;
            }
        }

        if ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign))
            Console.CursorVisible = false;

        #endregion
    }

    public static void ClearMovesBlackboard() // Изчиства полето за списъка 
    {
        Console.CursorVisible = false;
        Console.BackgroundColor = colorOfMovesBackground;
        Console.ForegroundColor = colorOfMovesForeground;

        for (pcmb = 0; pcmb <= 31; pcmb++)
        {
            Console.SetCursorPosition(48, pcmb);
            Console.Write(emptyBlackboardRow);
        }
    }

    public static void PreparingForPrintOfTheEndingMove() // Подготовка за отпечатване на заключителния ход от списъка 
    {
        Console.CursorVisible = false;

        if (realState == States.Draw)
        {
            Console.BackgroundColor = colorOfTheEndingDrawMoveBackground;
            Console.ForegroundColor = colorOfTheEndingDrawMoveForeground;
        }
        else if (realState == States.Checkmate)
        {
            Console.BackgroundColor = colorOfTheEndingCheckmateMoveBackground;
            Console.ForegroundColor = colorOfTheEndingCheckmateMoveForeground;
        }
        else if (realState == States.Resign)
        {
            Console.BackgroundColor = colorOfTheEndingResignMoveBackground;
            Console.ForegroundColor = colorOfTheEndingResignMoveForeground;
        }
    }

    #endregion

    #region Game Modes

    public static void Play()
    {
        switch (gameMode)
        {
            case GameModes.ComputerVsComputer:  { ComputerVsComputer(); break; }
            case GameModes.PlayerVsComputer:    { PlayerVsComputer();   break; }
            case GameModes.PlayerVsPlayer:      { PlayerVsPlayer();     break; }
            case GameModes.CheckMoveList:       { CheckMoveList();      break; }
            case GameModes.FinishGame:          { FinishGame();         break; }
            default: break;
        }

        Ending();
        //EndingOriginal();
    }

    public static void PlayerVsComputer()
    {
        if (gameMode != GameModes.FinishGame)
            StartingPosition();

        sound = true;

        while ((realState != States.Draw) && (realState != States.Checkmate) && (realState != States.Resign))
        {
            castle = Castles.noCastle;
            NextPCMove();
            if (hadNewGame)
                return;

            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits)
                && (savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == -2
                        || savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == 2))
                enPassantPreparing = (int)lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0] - 97;
            else
                enPassantPreparing = -9;

            if (realState != States.Resign)
                ChangePlayerToMove();
        }
    }

    public static void PlayerVsPlayer()
    {
        if (gameMode != GameModes.FinishGame)
            StartingPosition();

        sound = true;

        while ((realState != States.Draw) && (realState != States.Checkmate) && (realState != States.Resign))
        {
            castle = Castles.noCastle;
            NextMove();
            if (hadNewGame)
                return;

            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) 
                && (savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == -2 
                        || savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == 2))
                enPassantPreparing = (int)lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0] - 97;
            else
                enPassantPreparing = -9;

            //if (specialFigures.IndexOf(lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0]) == -1
            //    && someCastle.IndexOf(lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0]) == -1
            //    && 1 < lastMoves[playerToMove][lastMoves[playerToMove].Count - 1].Length
            //    && (lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][1] - lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][4] == -2
            //            || lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][1] - lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][4] == 2))
            //    enPassantPreparing = (int)lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0] - 97;
            //else
            //    enPassantPreparing = -9;

            if (realState != States.Resign) // in original this condition is not necessary and table will rotate at the end
                ChangePlayerToMove();
        }
    }

    public static void ComputerVsComputer(int finishGameFromMove = -1)
    {
        if (gameMode != GameModes.FinishGame)
            StartingPosition();

        sound = false;
        tb1 = false;

        while ((realState != States.Draw) && (realState != States.Checkmate) && (realState != States.Resign))
        {
            if (currentMove == finishGameFromMove)
                return;

            castle = Castles.noCastle;
            NextOnlyPCsMove();
            //NextOnlyPCsMoveFull(); //! САМО за тестове с пълно изчертаване на екрана и звук
            if (hadNewGame)
                return;
            
            ////////////
            if (realState == States.Draw)
                draws++;
            else if (realState == States.Checkmate)
            {
                if (lastMoves[0].Count == lastMoves[1].Count)
                {
                    wins[1]++;
                    loses[0]++;
                }
                else
                {
                    wins[0]++;
                    loses[1]++;
                }
            }
            else if (realState == States.Resign)
            {
                if (lastMoves[0].Count == lastMoves[1].Count)
                {
                    resigns[1]++;
                    wins[0]++;
                }
                else
                {
                    resigns[0]++;
                    wins[1]++;
                }
            }
            ////// +
            if ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign))
            {
                //FullPrint();
                Console.BackgroundColor = colorOfBottomHelpBackground;
                Console.ForegroundColor = colorOfBottomHelpForeground;
                //Console.SetCursorPosition(49, 0);
                //Console.Write(topHelp);
                Console.SetCursorPosition(49, 31);
                //Console.Write("Current mode: {0}  {1}  {2}={3}#{4}+{5}.{6}+{7}", gameModes[(int)gameMode], bottomHelp, sets, draws, wins[0], wins[1], resigns[0], resigns[1]);
                //Thread.Sleep(50);
            }
            /////////////

            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits)
                && (savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == -2
                        || savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == 2))
                enPassantPreparing = (int)lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0] - 97;
            else
                enPassantPreparing = -9;

            //! Закоментирах ЕДИНСТВЕНО за тестовете, тъй като в Ending() искам и Resign да се изказва правилно
            //if (realState != States.Resign)
                ChangePlayerToMove();
        }
    }

    public static void CheckMoveList()
    {
        StartingPosition();

        sound = false;

        //emptyRawMoveList = false;
        //emptyInappropriateMoveListArray = false;
        //emptyMoveList = false;

        if (!FillMoveList())
            return;

        //startTime = DateTime.Now;
        PrintBattlefield(lookingAngles[playerToMove]);

        while ((realState != States.Draw) && (realState != States.Checkmate) && (realState != States.Resign))
        {
            urongMove = false;
            //unwantedMove = false;
            castle = Castles.noCastle;
            NextMoveFromList(moveList[currentMove]);

            if (hadNewGame)
                return;

            if (urongMove)
            {
                ChangePlayerToMove();
                return;
            }

            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits)
                && (savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == -2
                        || savePositions[playerToMove][0][1] - savePositions[playerToMove][1][1] == 2))
                enPassantPreparing = (int)lastMoves[playerToMove][lastMoves[playerToMove].Count - 1][0] - 97;
            else
                enPassantPreparing = -9;

            ChangePlayerToMove();
        }

        FullPrint();
        Console.CursorVisible = false;
        //Console.SetCursorPosition(50, 31);
        //Console.Write("{0}", DateTime.Now - startTime);
    }

    public static void FinishGame()
    {
        do
        {
            StartingPosition();

            do
            {
                FullPrint();
                Console.CursorVisible = false;
                Console.SetCursorPosition(49, 1);
                Console.BackgroundColor = colorOfFinishGameFromMoveBackground;
                Console.ForegroundColor = colorOfFinishGameFromMoveForeground;
                Console.Write("   ");
                Console.SetCursorPosition(49, 1);
                Console.CursorVisible = true;
                if (int.TryParse(Console.ReadLine(), out finishGameFromMove))
                    if (0 <= finishGameFromMove)
                        break;

                Console.CursorVisible = false;
            } while (true);

            Console.CursorVisible = false;

            FullPrint();

            Console.CursorVisible = false;
            Console.SetCursorPosition(49, 1);
            Console.BackgroundColor = colorOfDefaultBackground;
            Console.ForegroundColor = colorOfDefaultForeground;
            Console.Write("   ");
            Console.BackgroundColor = colorOfFinishGameFromMoveBackground;
            Console.ForegroundColor = colorOfFinishGameFromMoveForeground;
            Console.SetCursorPosition(49, 1);
            Console.Write(finishGameFromMove);

            Console.SetCursorPosition(49, 31);
            Console.BackgroundColor = colorOfChoiseGameModeToFinishGameFromMoveBackground;
            Console.ForegroundColor = colorOfChoiseGameModeToFinishGameFromMoveForeground;
            Console.Write(" ");
            Console.SetCursorPosition(49, 31);
            Console.CursorVisible = true;

            choiseGameModeToFinishGameFromMove = (Console.ReadKey().KeyChar).ToString();
            Console.CursorVisible = false;
            changeGameModeBy = gameModes.IndexOf(choiseGameModeToFinishGameFromMove);
            if (changeGameModeBy != -1)
            {
                if ((GameModes)changeGameModeBy == GameModes.FinishGame)
                    continue;
                else if ((GameModes)changeGameModeBy == GameModes.CheckMoveList)
                {
                    gameMode = GameModes.CheckMoveList;
                    lookingAngles[0] = lookingAngles[1] = 0;
                    CheckMoveList();
                    break;
                }
                else if ((GameModes)changeGameModeBy == GameModes.ThroughMoves)
                {
                    if (finishGameFromMove == 0)
                        continue;
                }

                Thread.Sleep(timeAfterChoiseFinishGameFromMoveList);

                do
                {
                    ComputerVsComputer(finishGameFromMove);
                    if (currentMove == finishGameFromMove)
                        break;
                } while (true);

                if ((GameModes)changeGameModeBy == GameModes.PlayerVsComputer)
                {
                    playWith = playerToMove;
                    lookingAngles[playerToMove] = lookingAngles[oppositePlayer] = playerToMove * 2;
                    if (finishGameFromMove == 0)
                        printBeforeFirstMove = true;
                    else
                        printBeforeFirstMove = false;
                }
                else if ((GameModes)changeGameModeBy == GameModes.PlayerVsPlayer)
                {
                    lookingAngles[playerToMove] = playerToMove * 2;
                    lookingAngles[oppositePlayer] = oppositePlayer * 2;
                    printBeforeFirstMove = false;
                }
                else
                {
                    lookingAngles[0] = lookingAngles[1] = 0;
                    printBeforeFirstMove = false;
                }

                FullPrint();

                #region Say last computer move

                if (0 < finishGameFromMove)
                {
                    ChangePlayerToMove();
                    SayMove(MakeSentence());
                    ChangePlayerToMove();
                }

                #endregion

                switch ((GameModes)changeGameModeBy)
                {
                    case GameModes.ComputerVsComputer:  { ComputerVsComputer(); break; }
                    case GameModes.PlayerVsComputer:    { PlayerVsComputer();   break; }
                    case GameModes.PlayerVsPlayer:      { PlayerVsPlayer();     break; }
                    default: break;
                }

                break;
            }
        } while(true);
    }

    public static void Ending()
    {
        if (!hadNewGame)
        {
            // testCounter condition
            //if (realState == States.Checkmate)
            //    testCounterOf++;
            // testCounter condition
            //ti1 = gotMove.IndexOf("=");
            //ti2 = gotMove.IndexOf("+");

            //? Заспиване
            //if (sets % 150 == 0)
            //{
            //    Console.Clear();
            //    Console.WriteLine("{0} {1}",
            //        gameBothDifficulty[0] == Difficulty.Amateur ? "A" : (gameBothDifficulty[0] == Difficulty.Human ? "H" : "N"),
            //        gameBothDifficulty[1] == Difficulty.Amateur ? "A" : (gameBothDifficulty[1] == Difficulty.Human ? "H" : "N"));
            //    Console.WriteLine(sets);
            //    Console.Write("Sleep!");
            //    Thread.Sleep(5000);
            //}

            //if (true && ((((realState == States.Checkmate) && (gotMove.IndexOf("=N") != -1))) || (gameMode != GameModes.ComputerVsComputer)))
            //if (false && ((castle != Castles.noCastle) || (gameMode != GameModes.ComputerVsComputer)))
            //if (true && ((realState == States.Draw && currentMove % 2 == 0 && drawKind == drawByRepetition) || (gameMode != GameModes.ComputerVsComputer)))
            //if (true && ((gotMove.Length == 9 && gotMove[0] != '=') || (gameMode != GameModes.ComputerVsComputer)))
            if (true && ((sets % 38 == 0) || (gameMode != GameModes.ComputerVsComputer)))
            {
                // testCounter condition
                testCounterOf = 0;
                // testCounter condition

                duration = DateTime.Now - startTime;
                
                //Console.CursorVisible = false;
                //Console.SetCursorPosition(48, 0);
                //Console.BackgroundColor = colorOfDefaultBackground;
                //Console.ForegroundColor = colorOfDefaultForeground;
                //Console.Write(emptyBlackboardRow);
                //Console.SetCursorPosition(49, 0);
                ////Console.Write(playAgain);
                //Console.CursorVisible = true;

                FullPrint();

                //! Perfect!
                //Console.CursorVisible = false;
                //Console.SetCursorPosition(48, 0);
                //Console.BackgroundColor = colorOfDefaultBackground;
                //Console.ForegroundColor = colorOfDefaultForeground;
                //Console.Write(emptyBlackboardRow);
                //Console.SetCursorPosition(48, 0);

                totalSpeed = 0;

                // zero-
                oldSets = sets;

                //Console.Write("Sets: {0}  in Time: {3}", sets, oldSets - sets, DateTime.Now - startTime, duration); //! PERFECT!!!
                //Console.Write("{0} {3}", sets, oldSets - sets, DateTime.Now - startTime, duration);

                //-one
                sets = draws = wins[0] = wins[1] = resigns[0] = resigns[1] = 0; //! PERFECT!!!

                ChangePlayerToMove(); // за да се изказва вярно последния ход

                if (gameMode != GameModes.PlayerVsComputer)
                    SayMove(MakeSentence());

                Console.SetCursorPosition(49, 31);
                Console.BackgroundColor = colorOfGameModeChoiseAfterEndingBackground;
                Console.ForegroundColor = colorOfGameModeChoiseAfterEndingForeground;
                Console.Write(" ");
                Console.SetCursorPosition(49, 31);
                Console.CursorVisible = true;

                //changeGameModeByEventually = Console.ReadLine();
                changeGameModeByEventually = (Console.ReadKey().KeyChar).ToString();

                Console.CursorVisible = false;

                Thread.Sleep(timeAfterChoiseGameModeAfterEndingList);

                #region Change game mode

                changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
                if (changeGameModeBy != -1)
                    gameMode = (GameModes)changeGameModeBy;

                #endregion

                #region Game difficulty

                GameDifficulty(changeDifficulty.IndexOf(changeGameModeByEventually));

                #endregion

                #region Table rotation

                if (rotations.IndexOf(changeGameModeByEventually) != -1)
                {
                    Rotate(oppositePlayer, changeGameModeByEventually);
                    FullPrint();
                    Console.CursorVisible = false;
                    Thread.Sleep(200);
                }

                #endregion

                #region Blindfold

                if (changeGameModeByEventually.ToLower() == changeBlindfold)
                {
                    blindfold = !blindfold;
                    FullPrint();
                    Console.CursorVisible = false;
                    Thread.Sleep(200);
                }

                #endregion

                #region Sound

                if (changeGameModeByEventually.ToLower() == changeSound)
                    sound = !sound;

                #endregion

                startTime = DateTime.Now;
            }
        }
    }

    public static void EndingOriginal()
    {
        if (!hadNewGame)
        {
            Console.CursorVisible = false;
            Console.SetCursorPosition(48, 0);
            Console.BackgroundColor = colorOfDefaultBackground;
            Console.ForegroundColor = colorOfDefaultForeground;
            Console.Write(emptyBlackboardRow);
            Console.SetCursorPosition(49, 0);
            Console.Write(playAgain);
            Console.CursorVisible = true;
            //FullPrint();
            changeGameModeByEventually = Console.ReadLine();
            changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
            if (changeGameModeBy != -1)
                gameMode = (GameModes)changeGameModeBy;
        }
    }

    #endregion

    #region Moves players'

    #region Artificial Intelligence Engines

    public static void NextOnlyPCsMove()
    {
        #region Notation

        if (computerNotation != Notation.RandomAlgebraic)
            computerNotationCurrent = computerNotation;
        else
        {
            if (randomGenerator.Next(1, 101) <= 50)
                computerNotationCurrent = Notation.LongAlgebraic;
            else
                computerNotationCurrent = Notation.ShortAlgebraic;
        }

        #endregion

        enPassant = false;

        //FullPrint();
        //PrintLastMoves(true); // instead of FullPrint()
        //Console.CursorVisible = true;
        //if (!pressedNonSpecialButton)
        //    Thread.Sleep(timePCThinksMove);
        //Thread.Sleep(50); // instead of up two rows

        if (ButtonPressed())
            return;

        // това пък какво общо има и защо е изобщо тук!? Сетих се, че исках да стопирам играта при тестове, само когато има извършена рокада
        //if (!(castlePossibility[0][0]))// || castlePossibility[1][0]))
        //{
        //    realState = give = States.Resign;
        //    return;
        //}

        drawAfterMakeMove = false; // drawAfterMakeMove играе роля и за създаване на изречението в зависимост от стойността си, дори когато няма реми!

        // it looks like PCAnswersThePCDrawQuestion() on the next row is useless and think at all if
        if (PCAnswersThePCDrawQuestion() || CheckForPossibleResign() || ChecksForPossibleDraws(true) || OffersDrawByAgreement())
            return;

        //if (realState != States.Free)
        //    stateForCastle = 1;

        FindAllPossibleMoves();
        //FullPrint(); // САМО за тестове на totalSpeed
        totalSpeed += allPossibleMoves[playerToMove]; // САМО за тестове
        ChoosePossibleMove();
        drawAfterMakeMove = true;
        gotMove = buildTextOfMove.ToString();

        //if (give != States.Draw) // може би трябва да е само при give == States.Free, но дали още в ChoosePossibleMove() не проверявам същото!?
        if (give == States.Free || give == States.Check)
        {
            if (ChecksForPossibleDraws(false))
                return;
        }

        ///////////////Console.Write(gotMove);
        //Console.CursorVisible = false;

        realState = give;
        if ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign))
        {
            //! при Material-Repetition-Fifty, завършваме BuildTextOfMove()
            if (realState == States.Draw)
                if (drawKind != drawByStalemate)
                    gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;

            currentMove++;
            lastMoves[playerToMove].Add(gotMove);
            //AddCastleRestrictions(); // няма нужда
            //FullPrint();
            if (sound)
                SayMove(MakeSentence());

            return;
        }

        //Console.Write(gotMove);
        //Console.CursorVisible = false;
        //Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
        //PrintBattlefield(lookingAngles[playerToMove]);
        if (sound)
            SayMove(MakeSentence());

        AddCastleRestrictions();
        currentMove++;
        lastMoves[playerToMove].Add(gotMove);

        //! За тестове до края на функцията:
        // 
        //if (exchange)
        //{
        //FullPrint();
        //SayMove(MakeSentence());
        //Console.ReadKey();
        //}

        //if (gotMove.IndexOf(enPassantSymbol) != -1)
        //{
        //    FullPrint();
        //    SayMove(MakeSentence());
        //    Console.ReadKey();
        //    tb1 = true;
        //}
    }

    public static void NextOnlyPCsMoveFull()
    {
        sound = true; //! за всеки случай, тъй като NextOnlyPCsMoveFull() е само тестова и искам директен контрол върху звука

        FullPrint();
        PrintLastMoves(true); // instead of FullPrint()
        Console.CursorVisible = true;
        if (!pressedNonSpecialButton)
            Thread.Sleep(timePCThinksMove);
        Thread.Sleep(50); // instead of up two rows

        if (ButtonPressed())
            return;

        // това пък какво общо има и защо е изобщо тук!? Сетих се, че исках да стопирам играта при тестове, само когато има извършена рокада
        //if (!(castlePossibility[0][0]))// || castlePossibility[1][0]))
        //{
        //    realState = give = States.Resign;
        //    return;
        //}

        drawAfterMakeMove = false; // drawAfterMakeMove играе роля и за създаване на изречението в зависимост от стойността си, дори когато няма реми!

        // it looks like PCAnswersThePCDrawQuestion() on the next row is useless and think at all if
        if (PCAnswersThePCDrawQuestion() || CheckForPossibleResign() || ChecksForPossibleDraws(true) || OffersDrawByAgreement())
            return;

        //if (realState != States.Free)
        //    stateForCastle = 1;

        FindAllPossibleMoves();
        ChoosePossibleMove();
        drawAfterMakeMove = true;
        gotMove = buildTextOfMove.ToString();

        //if (give != States.Draw) // може би трябва да е само при give == States.Free, но дали още в ChoosePossibleMove() не проверявам същото!?
        if (give == States.Free || give == States.Check)
        {
            if (ChecksForPossibleDraws(false))
                return;
        }

        ///////////////Console.Write(gotMove);
        Console.CursorVisible = false;
        realState = give;
        if ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign))
        {
            //! при Material-Repetition-Fifty, завършваме BuildTextOfMove()
            if (realState == States.Draw)
                if (drawKind != drawByStalemate)
                    gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;

            currentMove++;
            lastMoves[playerToMove].Add(gotMove);
            FullPrint();
            if (sound)
                SayMove(MakeSentence());

            return;
        }

        Console.Write(gotMove);
        Console.CursorVisible = false;
        Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
        PrintBattlefield(lookingAngles[playerToMove]);
        if (sound)
            SayMove(MakeSentence());

        AddCastleRestrictions();
        currentMove++;
        lastMoves[playerToMove].Add(gotMove);

        // За тестове до края на функцията:
        // 
        //if (exchange)
        //{
        //FullPrint();
        //SayMove(MakeSentence());
        //Console.ReadKey();
        //}

        //if (gotMove.IndexOf("O+") != -1)
        //{
        //    FullPrint();
        //    SayMove(MakeSentence());
        //    Console.ReadKey();
        //    tb1 = true;
        //}
    }

    public static bool ButtonPressed()
    {
        buttonPressed = false;
        if (Console.KeyAvailable)
        {
            pressedSpecialButton = false;
            pressedNonSpecialButton = false;
            buttonPressed = true;
            PrintLastMoves(true);
            pressed = Console.ReadKey().KeyChar.ToString();
            Console.CursorVisible = false;
            hadRotation = false;
            hadBlindfoldChange = false;

            #region Start new game immediately

            hadNewGame = false;
            changeGameModeByEventually = pressed;
            changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
            if (changeGameModeBy != -1)
            {
                pressedSpecialButton = true;
                gameMode = (GameModes)changeGameModeBy;
                hadNewGame = true;
            }

            #endregion

            #region Game difficulty

            else if (changeDifficulty.IndexOf(pressed) != -1)
            {
                gameDifficulty = (Difficulty)changeDifficulty.IndexOf(pressed);
                pressedSpecialButton = true;
                Console.CursorVisible = false;
                ChangePlayerToMove();
            }

            #endregion

            #region Table rotation

            else if (rotations.IndexOf(pressed) != -1)
            {
                pressedSpecialButton = true;
                Rotate(oppositePlayer, pressed);
                hadRotation = true;
                ChangePlayerToMove();
                FullPrint();
                Console.CursorVisible = false;
            }

            #endregion

            #region Blindfold

            else if (pressed.ToLower() == changeBlindfold)
            {
                pressedSpecialButton = true;
                blindfold = !blindfold;
                hadBlindfoldChange = true;
                FullPrint();
                Console.CursorVisible = false;
                ChangePlayerToMove();
            }

            #endregion

            #region Sound

            else if (pressed.ToLower() == changeSound)
            {
                pressedSpecialButton = true;
                sound = !sound;
                PrintLastMoves(true);
                Console.CursorVisible = false;
                ChangePlayerToMove();
            }

            #endregion

            if (hadRotation || hadBlindfoldChange)
                Thread.Sleep(timeAfterRotationOrBlindfoldChangeBeforeNextMoveFromListOrPC);

            if (!pressedSpecialButton)
            {
                pressedNonSpecialButton = true;
                ChangePlayerToMove();
            }
        }

        return buttonPressed;
    }

    public static bool PCAnswersThePCDrawQuestion()
    {
        answerTheDrawQuestion = false;
        if (gotMove == drawQuestion)
        {
            //FullPrint();
            //Console.Write(drawQuestion);
            //Console.CursorVisible = true;
            //Thread.Sleep(timePCThinksMove);
            if (randomGenerator.Next(1, randomAcceptDrawByAgreementFrom[oppositePlayer] + 1) <= randomAcceptDrawByAgreement[oppositePlayer])
            {
                answerTheDrawQuestion = true;
                currentMove++;
                gotMove = drawByAgreement;
                lastMoves[playerToMove].Add(gotMove);
                give = States.Draw;
                realState = give;
                //FullPrint();
                if (sound)
                    SayMove(MakeSentence());
            }
            else
            {
                //Console.Write(drawAnswerRefuse);
                //Console.CursorVisible = false;
                if (sound)
                    SayMove(string.Format("{0}{1}", playWith == 0 ? "Black" : "White", " refuse draw by agreement!"));
            }
        }

        return answerTheDrawQuestion;
    }

    public static bool CheckForPossibleResign()
    {
        // only if there is addititional condition for testing !!!  start
        //if (4 <= currentMove)
        //{
        //    randomResign[playerToMove] = 100;
        //    randomResignFrom[playerToMove] = 100;
        //}
        // only if there is addititional condition for testing !!!  end

        givePossibleResign = false;
        if (randomGenerator.Next(1, randomResignFrom[playerToMove] + 1) <= randomResign[playerToMove])
        {
            // only if there is addititional condition for testing !!!  start  mai tova e gre6no i syvsem izli6no
            //if (4 <= currentMove)
            //{
            //    randomResign[playerToMove] = 1;
            //    randomResignFrom[playerToMove] = 10000;
            //}
            // only if there is addititional condition for testing !!!  end

            givePossibleResign = true;
            //Console.Write(gotMove);
            //Console.CursorVisible = false;
            gotMove = resign;
            currentMove++;
            lastMoves[playerToMove].Add(gotMove);
            give = States.Resign;
            realState = give;
            //FullPrint();
            if (sound)
                SayMove(MakeSentence());
        }

        return givePossibleResign;
    }

    public static bool ChecksForPossibleDraws(bool beforeMove)
    {
        givePossibleDraw = false;
        if ((((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop)) 
            && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop))) 
                && (randomGenerator.Next(1, randomDrawByMaterialFrom[playerToMove] + 1) <= randomDrawByMaterial[playerToMove]))
        {
            drawKind = drawByInsufficientMaterial;
            ChosenDraw(beforeMove);
        }
        else if ((3 <= maxMatches) && (randomGenerator.Next(1, randomDrawByRepetitionFrom[playerToMove] + 1) <= randomDrawByRepetition[playerToMove]))
        {
            drawKind = drawByRepetition;
            ChosenDraw(beforeMove);
        }
        else if (((50 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer])) 
            && (randomGenerator.Next(1, randomDrawByFiftyRuleFrom[playerToMove] + 1) <= randomDrawByFiftyRule[playerToMove]))
        {
            if (50 <= passiveMoves[0])
                drawKind = drawByWhiteFiftyMoveRule;
            else
                drawKind = drawByBlackFiftyMoveRule;

            ChosenDraw(beforeMove);
        }

        return givePossibleDraw;
    }

    public static bool OffersDrawByAgreement()
    {
        //! компютъра ВИНАГИ проверява дали има право преди да предложи пат на човек или друг компютър
        if (currentMove < drawQuestionOnMove + drawQuestionMoveInterval)
                return false;

        offersDrawByAgreement = false;
        if (randomGenerator.Next(1, randomOffersDrawByAgreementFrom[playerToMove] + 1) <= randomOffersDrawByAgreement[playerToMove])
        {
            drawQuestionOnMove = currentMove;
            offersDrawByAgreement = true;
            //Console.Write(drawQuestion);
            //Console.CursorVisible = false;
            if (sound)
                SayMove(string.Format("{0}{1}", playWith == 0 ? "Black" : "White", " offers draw by agreement!"));

            //Console.CursorVisible = true;
            //на следващия ред променям за проба Random отговора да е свързан именно с oppositePlayer
            if (((gameMode == GameModes.ComputerVsComputer) && (randomGenerator.Next(1, randomAcceptDrawByAgreementFrom[oppositePlayer] + 1) <= randomAcceptDrawByAgreement[oppositePlayer]))
                    || ((gameMode == GameModes.PlayerVsComputer) && (Console.ReadLine() == drawAnswer)))
            {
                Console.CursorVisible = false;
                gotMove = drawByAgreement;
                drawKind = drawByAgreement;
                currentMove++;
                lastMoves[playerToMove].Add(gotMove);
                give = States.Draw;
                realState = give;
                //FullPrint();
                if (sound)
                    SayMove(string.Format("{0}{1}", playWith == 0 ? "White" : "Black", "  accepts draw by agreement!"));

                return offersDrawByAgreement;
            }
            else
            {
                //Console.Write(drawAnswerRefuse);
                //Console.CursorVisible = false;
                if (sound)
                    SayMove(string.Format("{0}{1}", playWith == 0 ? "Black" : "White", " refuse draw by agreement!"));

                ChangePlayerToMove();
            }
        }

        return offersDrawByAgreement;
    }

    public static void ChosenDraw(bool chosenDrawBeforeMove)
    {
        givePossibleDraw = true;
        if (chosenDrawBeforeMove)
            gotMove = drawKind;
        else
            gotMove = gotMove + drawKind;

        currentMove++;
        lastMoves[playerToMove].Add(gotMove);
        give = States.Draw;
        realState = give;
        //FullPrint();
        if (sound)
            SayMove(MakeSentence());
    }

    public static void PCAnswerThePlayerDrawQuestion()
    {
        answerTheDrawQuestion = false;
        if (gotMove == drawQuestion)
        {
            //FullPrint();
            //Console.Write(drawQuestion);
            //Console.CursorVisible = true;
            //Thread.Sleep(timePCThinksMove);
            if (Console.ReadLine() == drawAnswer)
            {
                answerTheDrawQuestion = true;
                currentMove++;
                gotMove = drawByAgreement;
                lastMoves[playerToMove].Add(gotMove);
                realState = give;
                if (sound)
                    SayMove(MakeSentence());
            }
        }
    }

    public static void NextPCMove()
    {
        #region Notation

        if (computerNotation != Notation.RandomAlgebraic)
            computerNotationCurrent = computerNotation;
        else
        {
            if (randomGenerator.Next(1, 101) <= 50)
                computerNotationCurrent = Notation.LongAlgebraic;
            else
                computerNotationCurrent = Notation.ShortAlgebraic;
        }

        #endregion

        enPassant = false;

        #region Player's move

        if (playerToMove == playWith)
        {
            do
            {
                #region Printing before enter new move

                if ((0 < currentMove)
                    && (((gotMove.ToLower() != changeBlindfold) && (lookingAngles[0] == lookingAngles[1]))
                        || (gotMove.ToLower() == changeSound)))
                    PrintLastMoves(makesClean: true);
                else
                    FullPrint();

                #endregion

                #region Enter new move

                gotMove = Console.ReadLine();
                Console.CursorVisible = false;

                #endregion

                #region Pieces change

                if (currentMove == 0)
                {
                    if (gotMove == changePlayWith)
                    {
                        oppositePlayWith = playWith;
                        playWith = 1 - playWith;
                        lookingAngles[playerToMove] = lookingAngles[oppositePlayer] = 2 * playWith;
                        FullPrint();
                        Console.Write(gotMove);
                        Console.CursorVisible = false;
                        ChangePlayerToMove();
                        break;
                    }
                    else
                    {
                        FullPrint();
                        Console.Write(gotMove);
                        Console.CursorVisible = false;
                    }
                }

                #endregion

                #region Start new game immediately

                hadNewGame = false;
                changeGameModeByEventually = gotMove;
                changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
                if (changeGameModeBy != -1)
                {
                    gameMode = (GameModes)changeGameModeBy;
                    hadNewGame = true;
                    return;
                }

                #endregion

                #region Game difficulty

                if (changeDifficulty.IndexOf(gotMove) != -1)
                {
                    gameDifficulty = (Difficulty)changeDifficulty.IndexOf(gotMove);
                    ChangePlayerToMove();
                    return;
                }

                #endregion

                #region Table rotation

                if (rotations.IndexOf(gotMove) != -1)
                {
                    Rotate(playerToMove, gotMove);
                    PrintBattlefield(lookingAngles[playerToMove]);
                    ChangePlayerToMove();
                    return;
                }

                #endregion

                #region Blindfold

                if (gotMove.ToLower() == changeBlindfold)
                {
                    blindfold = !blindfold;
                    ChangePlayerToMove();
                    return;
                }

                #endregion

                #region Sound

                if (gotMove.ToLower() == changeSound)
                {
                    sound = !sound;
                    ChangePlayerToMove();
                    return;
                }

                #endregion

                #region Read move, validate checks and make it

                if (ReadMove() && IsLegalMove())
                {
                    if ((realState == States.Draw) || (realState == States.Resign))
                    {
                        //! Довършваме означението на последния ход, ако имаме специален пат
                        if ((realState == States.Draw)
                                && (drawKind != drawByStalemate))
                            gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;

                        currentMove++;
                        lastMoves[playerToMove].Add(gotMove);
                        FullPrint();
                        if (sound)
                            SayMove(MakeSentence());

                        return;
                    }

                    // repeat only for first move to make change color ot '1.'
                    if (currentMove == 0)
                    {
                        printBeforeFirstMove = false;
                        PrintLastMoves(); //! Заличава част от първия символ на хода
                    }
                    // repeat only for first move to make change color ot '1.'

                    Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
                    PrintBattlefield(lookingAngles[playerToMove]);
                    if (sound)
                        SayMove(MakeSentence());

                    if (gotMove == drawQuestion)
                    {
                        FullPrint();
                        Console.Write(drawQuestion);
                        Console.CursorVisible = true;
                        //Thread.Sleep(timePCThinksMove);
                        if (drawQuestionOnMove + drawQuestionMoveInterval <= currentMove)
                        {
                            drawQuestionOnMove = currentMove;
                            if (randomGenerator.Next(1, randomAcceptDrawByAgreementFrom[oppositePlayer] + 1) <= randomAcceptDrawByAgreement[oppositePlayer])
                            {
                                currentMove++;
                                gotMove = drawByAgreement;
                                lastMoves[playerToMove].Add(gotMove);
                                give = States.Draw;
                                realState = give;
                                FullPrint();
                                if (sound)
                                    SayMove(MakeSentence());

                                break;
                            }
                            else
                            {
                                printBeforeFirstMove = true;
                                Console.Write(drawAnswerRefuse);
                                Console.CursorVisible = false;
                                if (sound)
                                    SayMove(string.Format("{0}{1}", playWith == 0 ? "Black" : "White", " refuse draw by agreement!"));
                            }
                        }
                        else
                        {
                            printBeforeFirstMove = true;
                            Console.Write(drawAnswerRefuse);
                            Console.Write(drawQuestionOnMove + drawQuestionMoveInterval - currentMove);
                            Console.CursorVisible = false;
                            if (sound)
                                SayMove(string.Format("It left {0} {1} to possibility of new offers for draw!", drawQuestionOnMove + drawQuestionMoveInterval - currentMove, 1 < drawQuestionOnMove + drawQuestionMoveInterval - currentMove ? "moves" : "move"));
                        }

                        continue;
                    }

                    AddCastleRestrictions();
                    currentMove++;
                    lastMoves[playerToMove].Add(gotMove);
                    realState = give;
                    break;
                }

                #endregion

            } while (true);
        }

        #endregion

        #region PC's move

        else
        {
            FullPrint();
            Console.CursorVisible = true;
            //Thread.Sleep(timePCThinksMove);
            drawAfterMakeMove = false;
            if (CheckForPossibleResign() || ChecksForPossibleDraws(true) || OffersDrawByAgreement())
                return;

            //if (realState != States.Free)
            //    stateForCastle = 1;

            FindAllPossibleMoves();
            ChoosePossibleMove();
            drawAfterMakeMove = true;
            gotMove = buildTextOfMove.ToString();

            if (give == States.Free || give == States.Check)
            {
                if (ChecksForPossibleDraws(false))
                    return;
            } 
            
            //! Вместо горното
            //if (ChecksForPossibleDraws(false))
            //    return;

            realState = give;
            if ((realState == States.Draw) || (realState == States.Checkmate) || (realState == States.Resign))
            {
                //! при Material-Repetition-Fifty, завършваме BuildTextOfMove()
                if (realState == States.Draw)
                    if (drawKind != drawByStalemate)
                        gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;

                currentMove++;
                lastMoves[playerToMove].Add(gotMove);
                //AddCastleRestrictions(); // няма нужда
                //FullPrint();
                if (sound)
                    SayMove(MakeSentence());

                return;
            }

            Console.Write(gotMove);
            Console.CursorVisible = false;

            Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
            PrintBattlefield(lookingAngles[playerToMove]);
            if (sound)
                SayMove(MakeSentence());

            ////////// PCAnswerThePlayerDrawQuestion(); // maybe it's not necessary and is for recycle bin
            AddCastleRestrictions();
            currentMove++;
            lastMoves[playerToMove].Add(gotMove);
            //realState = give; //? смених му мястото и вече е по-горе
        }

        #endregion
    }

        #endregion

    public static void NextMoveFromList(string giveMove) // Следва ход от изиграна партия 
    {
        //! Закоментирано САМО по време на тестовете
        //if (currentMove == 0)
        //    Thread.Sleep(timeBeforeFirstMoveFromList);

        #region Button was pressed

        if (Console.KeyAvailable)
        {
            pressedSpecialButton = false;
            pressedNonSpecialButton = false;
            PrintLastMoves(true);
            pressed = Console.ReadKey().KeyChar.ToString();
            Console.CursorVisible = false;
            hadRotation = false;
            hadBlindfoldChange = false;

            #region Start new game immediately

            hadNewGame = false;
            changeGameModeByEventually = pressed;
            changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
            if (changeGameModeBy != -1)
            {
                pressedSpecialButton = true;
                gameMode = (GameModes)changeGameModeBy;
                hadNewGame = true;
            }

            #endregion

            #region Table rotation

            else if (rotations.IndexOf(pressed) != -1)
            {
                pressedSpecialButton = true;
                Rotate(oppositePlayer, pressed);
                hadRotation = true;
                ChangePlayerToMove();
                FullPrint();
                Console.CursorVisible = false;
            }

            #endregion

            #region Blindfold

            else if (pressed.ToLower() == changeBlindfold)
            {
                pressedSpecialButton = true;
                blindfold = !blindfold;
                hadBlindfoldChange = true;
                FullPrint();
                Console.CursorVisible = false;
                ChangePlayerToMove();
            }

            #endregion

            #region Sound

            else if (pressed.ToLower() == changeSound)
            {
                pressedSpecialButton = true;
                sound = !sound;
                PrintLastMoves(true);
                Console.CursorVisible = false;
                ChangePlayerToMove();
            }

            #endregion

            if (hadRotation || hadBlindfoldChange)
                Thread.Sleep(timeAfterRotationOrBlindfoldChangeBeforeNextMoveFromListOrPC);

            if (!pressedSpecialButton)
            {
                pressedNonSpecialButton = true;
                ChangePlayerToMove();
            }

            return;
        }

        #endregion

        else
        {
            if (currentMove == 0)
                PrintBattlefield(lookingAngles[playerToMove]);

            gotMove = giveMove;

            //! Добавено повторение САМО за тестове върху последния ход
            //if (currentMove == moveList.Count - 1)
            //    gotMove = giveMove;

            if (ReadMove() && IsLegalMove())
            {
                AddCastleRestrictions();

                //! Довършваме означението на последния ход, ако имаме специален пат
                if ((currentMove == moveList.Count - 1)
                    && (realState == States.Draw)
                    && (drawKind != drawByStalemate))
                {
                    if ((drawKind == drawByAgreementShort) || (drawKind == drawByAgreement))
                        gotMove = drawByAgreement;
                    else
                        gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;
                }

                realState = give;

                if ((currentMove == moveList.Count - 1) && (realState == States.Free || realState == States.Check))
                {
                    unfinishedList = true;
                    lastMoves[oppositePlayer].Add(unfinishedListNote);
                    FullPrint();
                    if (sound)
                        SayMove(unfinishedListNote);

                    return;
                }

                lastMoves[playerToMove].Add(gotMove);

                if (((currentMove < moveList.Count - 1) && (realState == States.Resign || realState == States.Checkmate || realState == States.Draw)))
                {
                    //urongMove = true;
                    unwantedMove = true;
                    lastMoves[oppositePlayer].Add(unwantedMoveNote);
                    FullPrint();
                    if (sound)
                        SayMove(urongMoveNote);

                    return;
                }

                currentMove++;

                ///////////////////////FullPrint();
                PrintLastMoves(true);
                Console.CursorVisible = false;
                //Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
                PrintBattlefield(lookingAngles[playerToMove]);
                if (sound)
                    SayMove(MakeSentence());

                if (gotMove.IndexOf(enPassantSymbol) != -1)
                    SayMove(MakeSentence());


                //Thread.Sleep(timeBeforeNextMoveFromList);
            }
            else
            {
                urongMove = true;
                lastMoves[playerToMove].Add(urongMoveNote);
                FullPrint();
                if (sound)
                    SayMove(urongMoveNote);

                return;
            }
        }
    }

    public static void NextMove() // На ход е човек 
    {
        do
        {
            #region Printing before enter new move

            if ((0 < currentMove)
                && (((gotMove.ToLower() != changeBlindfold) && (lookingAngles[0] == lookingAngles[1]))
                    || (gotMove.ToLower() == changeSound)))
                PrintLastMoves(makesClean: true);
            else
                FullPrint();

            #endregion

            #region Enter new move

            Console.CursorVisible = true;
            gotMove = Console.ReadLine();
            Console.CursorVisible = false;

            #endregion

            #region Button was pressed

                #region Start new game immediately

            hadNewGame = false;
            changeGameModeByEventually = gotMove;
            changeGameModeBy = gameModes.IndexOf(changeGameModeByEventually);
            if (changeGameModeBy != -1)
            {
                gameMode = (GameModes)changeGameModeBy;
                hadNewGame = true;
                return;
            }

                #endregion

                #region Table rotation

            if (rotations.IndexOf(gotMove) != -1)
            {
                Rotate(playerToMove, gotMove);
                PrintBattlefield(lookingAngles[playerToMove]);
                ChangePlayerToMove();
                return;
            }

                #endregion

                #region Blindfold

            if (gotMove.ToLower() == changeBlindfold)
            {
                blindfold = !blindfold;
                ChangePlayerToMove();
                return;
            }

                #endregion

                #region Sound

            if (gotMove.ToLower() == changeSound)
            {
                sound = !sound;
                ChangePlayerToMove();
                return;
            }

                #endregion

            #endregion

            #region Read move, validate checks and make it

            if (ReadMove() && IsLegalMove())
            {
                if ((realState == States.Draw) || (realState == States.Resign))
                {
                    //! Довършваме означението на последния ход, ако имаме специален пат
                    if ((realState == States.Draw) 
                            && (drawKind != drawByStalemate))
                        gotMove = gotMove.Remove(gotMove.Length - 1) + drawKind;

                    currentMove++;
                    lastMoves[playerToMove].Add(gotMove);
                    FullPrint();
                    if (sound)
                        SayMove(MakeSentence());

                    return;
                }

                Thread.Sleep(timeBetweenPrintMoveAndMoveFigure);
                PrintBattlefield(lookingAngles[playerToMove]);
                drawAfterMakeMove = true;
                if (sound)
                    SayMove(MakeSentence());

                if (gotMove == drawQuestion)
                {
                    FullPrint();
                    Console.Write(drawQuestion);
                    if (drawQuestionOnMove + drawQuestionMoveInterval <= currentMove)
                    {
                        drawQuestionOnMove = currentMove;
                        if (Console.ReadLine() == drawAnswer)
                        {
                            currentMove++;
                            gotMove = drawByAgreement;
                            lastMoves[playerToMove].Add(gotMove);
                            give = States.Draw;
                            realState = give;
                            FullPrint();
                            if (sound)
                                SayMove(MakeSentence());

                            break;
                        }
                        else
                        {
                            PrintLastMoves(true);
                            Console.Write(drawQuestion + drawAnswerRefuse);
                            Console.CursorVisible = false;
                            if (sound)
                                SayMove(string.Format("{0}{1}", playWith == 0 ? "Black" : "White", " refuse draw by agreement!"));
                        }
                    }
                    else
                    {
                        PrintLastMoves(true);
                        Console.Write(drawQuestion + drawAnswerRefuse);
                        Console.Write(drawQuestionOnMove + drawQuestionMoveInterval - currentMove);
                        Console.CursorVisible = false;
                        if (sound)
                            SayMove(string.Format("It left - {0} - {1} to possibility of new offers for draw!", drawQuestionOnMove + drawQuestionMoveInterval - currentMove, 1 < drawQuestionOnMove + drawQuestionMoveInterval - currentMove ? "moves" : "move"));
                    }

                    continue;
                }

                AddCastleRestrictions();
                currentMove++;
                lastMoves[playerToMove].Add(gotMove);
                realState = give;
                break;
            }

            #endregion

        } while (true);
    }

    public static bool Rotate(int player, string lastGotMove) // Ротация ОКОЛО масата 
    {
        for (rotate = 0; rotate < rotations.Count; rotate++)
            if (lastGotMove == rotations[rotate])
            {
                lookingAngle = lookingAngles[player];
                switch (rotate % 4)
                {
                    case 0: { lookingAngle = 2 * player; break; }
                    case 1: { lookingAngle++; break; }
                    case 2: { lookingAngle = 2 * player + 2; break; }
                    case 3: { lookingAngle += 3; break; }
                    default: break;
                }

                if (3 < lookingAngle)
                    lookingAngle -= 4;

                lookingAngles[player] = lookingAngle;
                if ((gameMode == GameModes.PlayerVsComputer) || (gameMode == GameModes.ComputerVsComputer) || (gameMode == GameModes.CheckMoveList))
                    lookingAngles[1 - player] = lookingAngle;

                return true;
            }

        return false;
    }

    public static bool ReadMove() // Въвеждане на човешки ход 
    {
        #region Preparation

        shortAlgebraic = false;
        longAlgebraic = false;
        rowsInMove = 0;
        columnsInMove = 0;
        movesInMove = 0;
        takesInMove = 0;
        enPassantInMove = 0;
        shortAlgebraicRow = -1;
        shortAlgebraicColumn = -1;
        shortAlgebraicHowManyFiguresCanJump = 0;

        enPassant = false;

        checkAndDraw = false;

        takes = false;
        exchange = false;

        #endregion

        drawAfterMakeMove = false;

        #region Resign

        if (gotMove == resign)
        {
            give = States.Resign;
            realState = give;
            return true;
        }

        #endregion

        #region Draw

            #region Draw by agreement

        if ((gotMove == drawQuestion)
                && ((gameMode == GameModes.PlayerVsPlayer) || (gameMode == GameModes.PlayerVsComputer) || (gameMode == GameModes.ComputerVsComputer) || (gameMode == GameModes.FinishGame)))
        {
            give = States.Draw;
            return true;
        }

        if (((gotMove == drawByAgreementShort) || (gotMove == drawByAgreement)) 
            && (gameMode == GameModes.CheckMoveList))
        {
            give = States.Draw;
            drawKind = drawByAgreementShort;
            realState = give;
            return true;
        }

            #endregion

            #region Draw by insufficient Material, by Repetition and by Fifty-rule

        if (gotMove == draw)
        {
            if ((((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                    && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop)))
                || (3 <= maxMatches)
                || (50 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer]))
            {
                if (3 <= maxMatches)
                    drawKind = drawByRepetition;
                else if (50 <= passiveMoves[0])
                    drawKind = drawByWhiteFiftyMoveRule;
                else if (50 <= passiveMoves[1])
                    drawKind = drawByBlackFiftyMoveRule;
                else
                    drawKind = drawByInsufficientMaterial;

                give = States.Draw;
                realState = give;
                return true;
            }
            else if (gameMode == GameModes.CheckMoveList)
            {
                gotMove = drawByAgreementShort;
                moveList[moveList.Count - 1] = gotMove;
                give = States.Draw;
                drawKind = drawByAgreement;
                realState = give;

                using (StreamWriter changeReadyMoveList = new StreamWriter("readyMoveList.txt", false, Encoding.GetEncoding("windows-1251")))
                {
                    changeReadyMoveList.Write(moveList[0].Trim());
                    for (ifml = 1; ifml < moveList.Count; ifml++)
                        changeReadyMoveList.Write(string.Format("\r\n{0}", moveList[ifml].Trim()));
                }

                return true;
            }
            else
                return false;
        }

            #endregion

        #endregion

        drawAfterMakeMove = true;

        #region Castle

        castle = Castles.noCastle;
        if (gotMove.IndexOf(someCastle) != -1)
        {
            if (gotMove == castleKingsideFree)
            {
                give = States.Free;
                castle = Castles.castleKingsideFree;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheck)
            {
                give = States.Check;
                castle = Castles.castleKingsideCheck;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideDraw)
            {
                give = States.Draw;
                castle = Castles.castleKingsideDraw;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheckAndDraw)
            {
                //checkAndDraw = true;
                give = States.Draw;
                castle = Castles.castleKingsideCheckAndDraw;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheckmate)
            {
                give = States.Checkmate;
                castle = Castles.castleKingsideCheckmate;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleQueensideFree)
            {
                give = States.Free;
                castle = Castles.castleQueensideFree;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheck)
            {
                give = States.Check;
                castle = Castles.castleQueensideCheck;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideDraw)
            {
                give = States.Draw;
                castle = Castles.castleQueensideDraw;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheckAndDraw)
            {
                //checkAndDraw = true;
                give = States.Draw;
                castle = Castles.castleQueensideCheckAndDraw;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheckmate)
            {
                give = States.Checkmate;
                castle = Castles.castleQueensideCheckmate;
                //castleQueenside = true;
                return true;
            }
            else
                return false;
        }

        #endregion

        #region General inspection by length of gotMove

        if ((gotMove.Length < 2) || (9 < gotMove.Length))
            return false;

        #endregion

        #region Creating of current queue

        readMove.Clear();
        for (mprmccq = 0; mprmccq < gotMove.Length; mprmccq++)
        {
            symbolInMove = gotMove[mprmccq];
            symbolNumberInMove = (int)symbolInMove;

            readMove.Enqueue(symbolInMove);

            if ((0 <= symbolNumberInMove - 49) && (symbolNumberInMove - 49 <= 7))
                rowsInMove++;
            else if ((0 <= symbolNumberInMove - 97) && (symbolNumberInMove - 97 <= 7))
                columnsInMove++;
            else if (symbolInMove == moveSymbol)
                movesInMove++;
            else if (symbolInMove == takeSymbol)
                takesInMove++;
            else if (symbolInMove == enPassantSymbol)
                enPassantInMove++;
        }

        #endregion

        #region General inspection by counters in gotMove

        if ((rowsInMove < 1) || (2 < rowsInMove) || (columnsInMove < 1) || (2 < columnsInMove) || (1 < movesInMove + takesInMove + enPassantInMove))
            return false;

        #endregion

        #region Short or Long Algebraic Notation

        //if ((0 < movesInMove) || ((0 < takesInMove + enPassantInMove) && ((rowsInMove + columnsInMove == 2) || (rowsInMove + columnsInMove == 4))))
        if (rowsInMove + columnsInMove == 4)
            longAlgebraic = true;
        else
            shortAlgebraic = true;

        #endregion

        gotMoveReserve = gotMove;

        #region Player's to move catch the figure

        savePositions[playerToMove][0][0] = specialFigures.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][0][0] != -1)
        {
            if (playerToMove == 0)
                savePositions[playerToMove][0][0] += whiteNight;
            else
                savePositions[playerToMove][0][0] += blackNight;

            readMove.Dequeue();
            if (longAlgebraic)
            {
                if (readMove.Count < 5)
                    return false;
            }
            else // shortAlgebraic
                gotMove = gotMove.Remove(0, 1);
        }
        else
        {
            savePositions[playerToMove][0][0] = allColumns.IndexOf(readMove.Peek());
            if (savePositions[playerToMove][0][0] == -1)
                return false;

            if (playerToMove == 0)
                savePositions[playerToMove][0][0] = whitePawn;
            else
                savePositions[playerToMove][0][0] = blackPawn;
        }

        #endregion

        #region !!! ONLY Short AlgebraicNotation end of reading ONLY !!!

        if (shortAlgebraic)
        {
            #region Анонс

            give = States.Free;

            if ((gotMove[gotMove.Length - 1] == checkSymbol) || (gotMove[gotMove.Length - 1] == checkmateSymbol) || (gotMove[gotMove.Length - 1] == drawSymbol))
            {
                if (gotMove.Length < 3)
                    return false;

                if (gotMove[gotMove.Length - 1] == checkSymbol)
                    give = States.Check;
                else if (gotMove[gotMove.Length - 1] == checkmateSymbol)
                    give = States.Checkmate;
                else
                    give = States.Draw;

                gotMove = gotMove.Remove(gotMove.Length - 1);
                if (gotMove[gotMove.Length - 1] == checkSymbol)
                {
                    if ((give != States.Draw) || (gotMove.Length < 3))
                        return false;
                    else
                    {
                        checkAndDraw = true;
                        gotMove = gotMove.Remove(gotMove.Length - 1);
                    }
                }
            }

            #endregion

            #region Замяна

            exchangeWith = specialFigures.IndexOf(gotMove[gotMove.Length - 1]);
            if (exchangeWith != -1)
            {
                if (gotMove.Length < 4)
                    return false;

                if (gotMove[gotMove.Length - 2] != exchangeSymbol)
                    return false;

                exchange = true;
                exchangeWith += figures[playerToMove][0][0] - kingUnits + nightUnits;
                gotMove = gotMove.Remove(gotMove.Length - 2);
            }

            #endregion

            #region Главна проверка по дължина

            if (gotMove.Length < 2)
                return false;

            #endregion

            #region to Row

            savePositions[playerToMove][1][1] = (int)gotMove[gotMove.Length - 1] - 49;
            if ((savePositions[playerToMove][1][1] < 0) || (7 < savePositions[playerToMove][1][1]))
                return false;

            gotMove = gotMove.Remove(gotMove.Length - 1);

            #endregion

            #region to Column

            savePositions[playerToMove][1][2] = allColumns.IndexOf(gotMove[gotMove.Length - 1]);
            if (savePositions[playerToMove][1][2] == -1)
                return false;

            gotMove = gotMove.Remove(gotMove.Length - 1);
            savePositions[playerToMove][1][0] = battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]];

            #endregion

            #region Главна проверка по дължина

            if (2 < gotMove.Length)
                return false;

            #endregion

            #region Ан Пасан

            if (1 == takesInMove 
                && battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]] == emptyField 
                && savePositions[playerToMove][0][0] % 10 == pawnUnits)
            {
                takesInMove = 0;
                enPassantInMove = 1;
                gotMove = string.Format("{0}{1}", gotMove.Remove(gotMove.Length - 1), enPassantSymbol);
            }

            if (0 < enPassantInMove)
            {
                if (gotMove.Length != 2)
                    return false;

                if (gotMove[gotMove.Length - 1] != enPassantSymbol)
                    return false;

                if (savePositions[playerToMove][0][0] % 10 != pawnUnits)
                    return false;

                enPassant = true;
                takes = true;
                gotMove = gotMove.Remove(gotMove.Length - 1); // премахваме знака ':'
                savePositions[playerToMove][0][2] = allColumns.IndexOf(gotMove[0]);
                if (savePositions[playerToMove][0][2] == -1)
                    return false;

                if (playerToMove == 0)
                    savePositions[playerToMove][0][1] = 4;
                else
                    savePositions[playerToMove][0][1] = 3;
            }

            #endregion
                
            #region Обикновено вземане

            else if (0 < takesInMove)
            {
                if (gotMove[gotMove.Length - 1] != takeSymbol)
                    return false;

                takes = true;
                gotMove = gotMove.Remove(gotMove.Length - 1);

                if (1 < gotMove.Length)
                    return false;

                if (gotMove.Length == 0)
                {
                    if (savePositions[playerToMove][0][0] % 10 == pawnUnits)
                        return false;
                    
                    if (savePositions[playerToMove][0][0] % 10 == kingUnits)
                    {
                        savePositions[playerToMove][0][1] = figures[playerToMove][1][0];
                        savePositions[playerToMove][0][2] = figures[playerToMove][2][0];
                    }
                    else
                    {
                        for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                        {
                            if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                            {
                                switch (figures[playerToMove][0][mprmosao] % 10)
                                {
                                    case queenUnits:
                                        {
                                            if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case rookUnits:
                                        {
                                            if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case bishopUnits:
                                        {
                                            if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case nightUnits:
                                        {
                                            if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    default: break;
                                }
                            }
                        }

                        if (shortAlgebraicHowManyFiguresCanJump != 1)
                            return false;
                    }
                }
                else //! gotMove.Length == 1
                {
                    if (savePositions[playerToMove][0][0] % 10 == kingUnits)
                        return false;

                    if (savePositions[playerToMove][0][0] % 10 == pawnUnits)
                    {
                        savePositions[playerToMove][0][2] = allColumns.IndexOf(gotMove[0]);
                        if (savePositions[playerToMove][0][2] == -1)
                            return false;

                        if (playerToMove == 0)
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] - 1;
                        else
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] + 1;
                    }
                    else
                    {
                        savePositions[playerToMove][0][1] = (int)gotMove[0] - 49;
                        if ((0 <= savePositions[playerToMove][0][1]) && (savePositions[playerToMove][0][1] <= 7))
                        {
                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump < 2)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump != 1)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                {
                                    if (figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                        continue;

                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump == 0) //! колоната е пред реда при запис!!!
                                return false;
                        }
                        else //! savePositions[playerToMove][0][1] е ГРЕШНО
                        {
                            savePositions[playerToMove][0][2] = allColumns.IndexOf(gotMove[0]);
                            if (savePositions[playerToMove][0][2] == -1)
                                return false;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump < 2)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump != 1)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                {
                                    if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                        continue;

                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump != 0)
                                return false;
                        }
                    }
                }
            }

            #endregion

            #region Само преместване

            else
            {
                #region Пешка

                if (savePositions[playerToMove][0][0] % 10 == pawnUnits)
                {
                    if (0 < gotMove.Length)
                        return false;

                    savePositions[playerToMove][0][2] = savePositions[playerToMove][1][2];
                    if (playerToMove == 0)
                    {
                        if (savePositions[playerToMove][1][1] < 2)
                            return false;
                        else if (battlefield[savePositions[playerToMove][1][1] - 1, savePositions[playerToMove][1][2]] == whitePawn)
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] - 1;
                        else if (savePositions[playerToMove][1][1] < 3)
                            return false;
                        else if (battlefield[savePositions[playerToMove][1][1] - 2, savePositions[playerToMove][1][2]] == whitePawn)
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] - 2;
                        else
                            return false;
                    }
                    else
                    {
                        //! dyni se
                        if (5 < savePositions[playerToMove][1][1])
                            return false;
                        else if (battlefield[savePositions[playerToMove][1][1] + 1, savePositions[playerToMove][1][2]] == blackPawn)
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] + 1;
                        else if (4 < savePositions[playerToMove][1][1])
                            return false;
                        else if (battlefield[savePositions[playerToMove][1][1] + 2, savePositions[playerToMove][1][2]] == blackPawn)
                            savePositions[playerToMove][0][1] = savePositions[playerToMove][1][1] + 2;
                        else
                            return false;
                    }
                }

                #endregion

                #region Цар

                else if (savePositions[playerToMove][0][0] % 10 == kingUnits)
                {
                    if (0 < gotMove.Length)
                        return false;

                    savePositions[playerToMove][0][1] = figures[playerToMove][1][0];
                    savePositions[playerToMove][0][2] = figures[playerToMove][2][0];
                }

                #endregion

                #region Друга фигура

                else
                {
                    #region Главна проверка по дължина

                    if (2 < gotMove.Length)
                        return false;

                    #endregion

                    #region Единствена възможна фигура

                    if (gotMove.Length == 0)
                    {
                        for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                        {
                            if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                            {
                                switch (figures[playerToMove][0][mprmosao] % 10)
                                {
                                    case queenUnits:
                                        {
                                            if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case rookUnits:
                                        {
                                            if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case bishopUnits:
                                        {
                                            if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case nightUnits:
                                        {
                                            if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                {
                                                    savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                    savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                }

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    default: break;
                                }
                            }
                        }

                        if (shortAlgebraicHowManyFiguresCanJump != 1)
                            return false;
                    }

                    #endregion

                    #region Една на реда или колоната

                    else if (gotMove.Length == 1)
                    {
                        savePositions[playerToMove][0][1] = (int)gotMove[0] - 49;
                        if ((0 <= savePositions[playerToMove][0][1]) && (savePositions[playerToMove][0][1] <= 7))
                        {
                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump < 2)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][2] = figures[playerToMove][2][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump != 1)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                {
                                    if (figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                        continue;

                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump == 0) //! колоната е пред реда при запис!!!
                                return false;
                        }
                        else //! savePositions[playerToMove][0][1] е ГРЕШНО
                        {
                            savePositions[playerToMove][0][2] = allColumns.IndexOf(gotMove[0]);
                            if (savePositions[playerToMove][0][2] == -1)
                                return false;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump < 2)
                                return false;

                            shortAlgebraicHowManyFiguresCanJump = 0;

                            for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            {
                                if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                {
                                    switch (figures[playerToMove][0][mprmosao] % 10)
                                    {
                                        case queenUnits:
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case rookUnits:
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case bishopUnits:
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        case nightUnits:
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                    {
                                                        savePositions[playerToMove][0][1] = figures[playerToMove][1][mprmosao];
                                                        shortAlgebraicHowManyFiguresCanJump++;
                                                    }

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }

                                                break;
                                            }
                                        default: break;
                                    }
                                }
                            }

                            if (shortAlgebraicHowManyFiguresCanJump != 1)
                                return false;

                            //shortAlgebraicHowManyFiguresCanJump = 0;

                            //if (gotMoveReserve == "Rac1")
                            //{ }

                            //for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                            //{
                            //    if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                            //    {
                            //        if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                            //            continue;

                            //        switch (figures[playerToMove][0][mprmosao] % 10)
                            //        {
                            //            case queenUnits:
                            //                {
                            //                    if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                            //                    {
                            //                        MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                        if (!Checks(playerToMove))
                            //                            shortAlgebraicHowManyFiguresCanJump++;

                            //                        MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                    }

                            //                    break;
                            //                }
                            //            case rookUnits:
                            //                {
                            //                    if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                            //                    {
                            //                        MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                        if (!Checks(playerToMove))
                            //                            shortAlgebraicHowManyFiguresCanJump++;

                            //                        MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                    }

                            //                    break;
                            //                }
                            //            case bishopUnits:
                            //                {
                            //                    if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                            //                    {
                            //                        MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                        if (!Checks(playerToMove))
                            //                            shortAlgebraicHowManyFiguresCanJump++;

                            //                        MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                    }

                            //                    break;
                            //                }
                            //            case nightUnits:
                            //                {
                            //                    if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                            //                    {
                            //                        MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                        if (!Checks(playerToMove))
                            //                            shortAlgebraicHowManyFiguresCanJump++;

                            //                        MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                            //                    }

                            //                    break;
                            //                }
                            //            default: break;
                            //        }
                            //    }
                            //}

                            //if (shortAlgebraicHowManyFiguresCanJump != 0)
                                //return false; //! tuk!!! gre6no da proverqvame
                        }
                    }

                    #endregion

                    #region Една на реда и една на колоната

                    else // gotMove.Length == 2
                    {
                        savePositions[playerToMove][0][1] = (int)gotMove[gotMove.Length - 1] - 49;
                        if ((savePositions[playerToMove][0][1] < 0) || (7 < savePositions[playerToMove][0][1]))
                            return false;

                        gotMove = gotMove.Remove(gotMove.Length - 1);

                        savePositions[playerToMove][0][2] = allColumns.IndexOf(gotMove[gotMove.Length - 1]);
                        if (savePositions[playerToMove][0][2] == -1)
                            return false;

                        gotMove = gotMove.Remove(gotMove.Length - 1);

                        if (ReturnIndexOfFigure(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2]) == -1)
                            return false;

                        if (figures[playerToMove][savePositions[playerToMove][0][1]][savePositions[playerToMove][0][2]] != savePositions[playerToMove][0][0])
                            return false;

                        for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                        {
                            if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                            {
                                switch (figures[playerToMove][0][mprmosao] % 10)
                                {
                                    case queenUnits:
                                        {
                                            if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                            {
                                                if (!JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                    return false;

                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                else
                                                    return false;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }
                                            else
                                            {
                                                if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }
                                            }

                                            break;
                                        }
                                    case rookUnits:
                                        {
                                            if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                            {
                                                if (!JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                    return false;

                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                else
                                                    return false;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }
                                            else
                                            {
                                                if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }
                                            }

                                            break;
                                        }
                                    case bishopUnits:
                                        {
                                            if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                            {
                                                if (!JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                    return false;

                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                else
                                                    return false;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }
                                            else
                                            {
                                                if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }
                                            }

                                            break;
                                        }
                                    case nightUnits:
                                        {
                                            if (figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                                            {
                                                if (!JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                    return false;

                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;
                                                else
                                                    return false;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }
                                            else
                                            {
                                                if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                                {
                                                    MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                    if (!Checks(playerToMove))
                                                        shortAlgebraicHowManyFiguresCanJump++;

                                                    MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                }
                                            }

                                            break;
                                        }
                                    default: break;
                                }
                            }
                        }

                        if (shortAlgebraicHowManyFiguresCanJump < 2)
                            return false;

                        shortAlgebraicHowManyFiguresCanJump = 0;

                        for (mprmosao = 0; mprmosao < figures[playerToMove][0].Count; mprmosao++)
                        {
                            if (figures[playerToMove][0][mprmosao] == savePositions[playerToMove][0][0] && figures[playerToMove][2][mprmosao] == savePositions[playerToMove][0][2])
                            {
                                if (figures[playerToMove][1][mprmosao] == savePositions[playerToMove][0][1])
                                    continue;

                                switch (figures[playerToMove][0][mprmosao] % 10)
                                {
                                    case queenUnits:
                                        {
                                            if (JumpOfQueen(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case rookUnits:
                                        {
                                            if (JumpOfRook(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }
                                            
                                            break;
                                        }
                                    case bishopUnits:
                                        {
                                            if (JumpOfBishop(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case nightUnits:
                                        {
                                            if (JumpOfNight(figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], figures[playerToMove][0][mprmosao], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][mprmosao], figures[playerToMove][1][mprmosao], figures[playerToMove][2][mprmosao], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    default: break;
                                }
                            }
                        }

                        if (shortAlgebraicHowManyFiguresCanJump == 0)
                            return false;
                    }

                    #endregion
                }

                #endregion
            }

            #endregion

            if (savePositions[playerToMove][0][1] < 0 || 7 < savePositions[playerToMove][0][1]
                    || savePositions[playerToMove][0][2] < 0 || 7 < savePositions[playerToMove][0][2])
                return false;

            gotMove = gotMoveReserve;

            return true;
        }

        #endregion

        #region from field with column

        savePositions[playerToMove][0][2] = allColumns.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][0][2] == -1)
            return false;

        readMove.Dequeue();

        #endregion

        #region and row

        savePositions[playerToMove][0][1] = (int)readMove.Peek() - 49;
        if ((savePositions[playerToMove][0][1] < 0) || (7 < savePositions[playerToMove][0][1]))
            return false;

        readMove.Dequeue();

        #endregion

        #region and moves it to (and takes the figure on)

        if (readMove.Peek() == takeSymbol)
            takes = true;
        else if (readMove.Peek() == enPassantSymbol)
        {
            takes = true;
            enPassant = true;
        }
        else if (readMove.Peek() != moveSymbol)
            return false;

        readMove.Dequeue();

        #endregion

        #region field with column

        savePositions[playerToMove][1][2] = allColumns.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][1][2] == -1)
            return false;

        readMove.Dequeue();

        #endregion

        #region and row

        savePositions[playerToMove][1][1] = (int)readMove.Peek() - 49;
        if ((savePositions[playerToMove][1][1] < 0) || (7 < savePositions[playerToMove][1][1]))
            return false;

        //! при ан пасан savePositions[playerToMove][1][0] = 0
        savePositions[playerToMove][1][0] = battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]];

        if (takes 
            && !enPassant 
            && battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]] == emptyField 
            && savePositions[playerToMove][0][0] % 10 == pawnUnits)
        {
            enPassant = true;
            gotMove = gotMove.Replace(takeSymbol, enPassantSymbol);
        }

        #endregion

        #region (exchange pawn with...) and give...

        readMove.Dequeue();
        if (readMove.Count == 0)
        {
            give = States.Free;
            return true;
        }
        else if (readMove.Count == 1)
        {
            if (readMove.Peek() == checkSymbol)
                give = States.Check;
            else if (readMove.Peek() == drawSymbol)
                give = States.Draw;
            else if (readMove.Peek() == checkmateSymbol)
                give = States.Checkmate;
            else
                return false;

            return true;
        }
        else if ((readMove.Count == 2) || (readMove.Count == 3) || (readMove.Count == 4))
        {
            if (enPassant)
                return false; //! a4:b5=(Stalemate и {=?= в режим CheckMoveList}), но a4:b5+=(FMR) е НЕВЪЗМОЖНО! и изобщо специален пат след ан пасан

            // оправи го, защото така изхвърля с false при ход [Q(N)]a7xb8{=N}"+"=(Material[/"Stalemate"/Repetition/Fifty])
            // N a7xc6   +   =
            //    a7xa8   =   N
            //    a7xa8   =   N +
            //    a7xa8   =   N =
            //    a7xa8   =   N #
            //    a7xa8   =   N +=

            if ((readMove.Peek() == checkSymbol) && (readMove.Count == 2))
                checkAndDraw = true;
            else if (!((readMove.Peek() == exchangeSymbol) && (savePositions[playerToMove][0][0] % 10 == pawnUnits)))
                return false;

            readMove.Dequeue();
            if (checkAndDraw)
            {
                if (readMove.Peek() != drawSymbol)
                    return false;
                else
                {
                    give = States.Draw;
                    return true;
                }
            }

            exchangeWith = specialFigures.IndexOf(readMove.Peek());
            if (exchangeWith == -1)
                return false;

            exchange = true;
            exchangeWith += figures[playerToMove][0][0] - kingUnits + nightUnits;
            if (readMove.Count == 1)
                return true;

            readMove.Dequeue();
            if (readMove.Count == 1)
            {
                if (readMove.Peek() == checkSymbol)
                    give = States.Check;
                else if (readMove.Peek() == drawSymbol)
                    give = States.Draw;
                else if (readMove.Peek() == checkmateSymbol)
                    give = States.Checkmate;
                else
                    return false;

                return true;
            }

            if (readMove.Peek() != checkSymbol)
                return false;

            readMove.Dequeue();
            if (readMove.Peek() != drawSymbol)
                return false;

            checkAndDraw = true;
            return true;
        }
        else
            return false;

        #endregion
    }

    public static bool ReadMoveOld() //! СТАРО Въвеждане на човешки ход 
    {
        enPassant = false;

        checkAndDraw = false;

        takes = false;
        exchange = false;

        drawAfterMakeMove = false;

        #region Resign

        if (gotMove == resign)
        {
            give = States.Resign;
            realState = give;
            return true;
        }

        #endregion

        #region Draw

        #region Draw by agreement

        if ((gotMove == drawQuestion)
                && ((gameMode == GameModes.PlayerVsPlayer) || (gameMode == GameModes.PlayerVsComputer) || (gameMode == GameModes.ComputerVsComputer)))
        {
            give = States.Draw;
            return true;
        }

        if (((gotMove == drawByAgreementShort) || (gotMove == drawByAgreement))
            && (gameMode == GameModes.CheckMoveList))
        {
            give = States.Draw;
            drawKind = drawByAgreementShort;
            realState = give;
            return true;
        }

        #endregion

        #region Draw by insufficient Material, by Repetition and by Fifty-rule

        if (gotMove == draw)
        {
            if ((((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                    && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop)))
                || (3 <= maxMatches)
                || (50 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer]))
            {
                if (3 <= maxMatches)
                    drawKind = drawByRepetition;
                else if (50 <= passiveMoves[0])
                    drawKind = drawByWhiteFiftyMoveRule;
                else if (50 <= passiveMoves[1])
                    drawKind = drawByBlackFiftyMoveRule;
                else
                    drawKind = drawByInsufficientMaterial;

                give = States.Draw;
                realState = give;
                return true;
            }
            else
                return false;
        }

        #endregion

        #endregion

        drawAfterMakeMove = true;

        #region Castle

        castle = Castles.noCastle;
        if (gotMove.IndexOf(someCastle) != -1)
        {
            if (gotMove == castleKingsideFree)
            {
                give = States.Free;
                castle = Castles.castleKingsideFree;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheck)
            {
                give = States.Check;
                castle = Castles.castleKingsideCheck;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideDraw)
            {
                give = States.Draw;
                castle = Castles.castleKingsideDraw;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheckAndDraw)
            {
                //checkAndDraw = true;
                give = States.Draw;
                castle = Castles.castleKingsideCheckAndDraw;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleKingsideCheckmate)
            {
                give = States.Checkmate;
                castle = Castles.castleKingsideCheckmate;
                //castleKingside = true;
                return true;
            }
            else if (gotMove == castleQueensideFree)
            {
                give = States.Free;
                castle = Castles.castleQueensideFree;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheck)
            {
                give = States.Check;
                castle = Castles.castleQueensideCheck;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideDraw)
            {
                give = States.Draw;
                castle = Castles.castleQueensideDraw;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheckAndDraw)
            {
                //checkAndDraw = true;
                give = States.Draw;
                castle = Castles.castleQueensideCheckAndDraw;
                //castleQueenside = true;
                return true;
            }
            else if (gotMove == castleQueensideCheckmate)
            {
                give = States.Checkmate;
                castle = Castles.castleQueensideCheckmate;
                //castleQueenside = true;
                return true;
            }
            else
                return false;
        }

        #endregion

        #region General inspection by length of gotMove

        if ((gotMove.Length < 5) || (9 < gotMove.Length))
            return false;

        #endregion

        #region Creating of current queue

        readMove.Clear();
        for (mprmccq = 0; mprmccq < gotMove.Length; mprmccq++)
            readMove.Enqueue(gotMove[mprmccq]);

        #endregion

        #region Player's to move catch the figure

        savePositions[playerToMove][0][0] = specialFigures.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][0][0] != -1)
        {
            if (playerToMove == 0)
                savePositions[playerToMove][0][0] += whiteDecimals + nightUnits;
            else
                savePositions[playerToMove][0][0] += blackDecimals + nightUnits;

            readMove.Dequeue();
            if (readMove.Count < 5)
                return false;
        }
        else
        {
            if (playerToMove == 0)
                savePositions[playerToMove][0][0] = whiteDecimals + pawnUnits;
            else
                savePositions[playerToMove][0][0] = blackDecimals + pawnUnits;
        }

        #endregion

        #region from field with column

        savePositions[playerToMove][0][2] = allColumns.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][0][2] == -1)
            return false;

        readMove.Dequeue();

        #endregion

        #region and row

        savePositions[playerToMove][0][1] = (int)readMove.Peek() - 49;
        if ((savePositions[playerToMove][0][1] < 0) || (7 < savePositions[playerToMove][0][1]))
            return false;

        readMove.Dequeue();

        #endregion

        #region and moves it to (and takes the figure on)

        if (readMove.Peek() == takeSymbol)
            takes = true;
        else if (readMove.Peek() == enPassantSymbol)
        {
            takes = true;
            enPassant = true;
        }
        else if (readMove.Peek() != moveSymbol)
            return false;

        readMove.Dequeue();

        #endregion

        #region field with column

        savePositions[playerToMove][1][2] = allColumns.IndexOf(readMove.Peek());
        if (savePositions[playerToMove][1][2] == -1)
            return false;

        readMove.Dequeue();

        #endregion

        #region and row

        savePositions[playerToMove][1][1] = (int)readMove.Peek() - 49;
        if ((savePositions[playerToMove][1][1] < 0) || (7 < savePositions[playerToMove][1][1]))
            return false;

        //! при ан пасан savePositions[playerToMove][1][0] = 0
        savePositions[playerToMove][1][0] = battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]];

        #endregion

        #region (exchange pawn with...) and give...

        readMove.Dequeue();
        if (readMove.Count == 0)
        {
            give = States.Free;
            return true;
        }
        else if (readMove.Count == 1)
        {
            if (readMove.Peek() == checkSymbol)
                give = States.Check;
            else if (readMove.Peek() == drawSymbol)
                give = States.Draw;
            else if (readMove.Peek() == checkmateSymbol)
                give = States.Checkmate;
            else
                return false;

            return true;
        }
        else if ((readMove.Count == 2) || (readMove.Count == 3) || (readMove.Count == 4))
        {
            if (enPassant)
                return false; //! a4:b5=(Stalemate и {=?= в режим CheckMoveList}), но a4:b5+=(FMR) е НЕВЪЗМОЖНО! и изобщо специален пат след ан пасан

            // оправи го, защото така изхвърля с false при ход [Q(N)]a7xb8{=N}"+"=(Material[/"Stalemate"/Repetition/Fifty])
            // N a7xc6   +   =
            //    a7xa8   =   N
            //    a7xa8   =   N +
            //    a7xa8   =   N =
            //    a7xa8   =   N #
            //    a7xa8   =   N +=

            if ((readMove.Peek() == checkSymbol) && (readMove.Count == 2))
                checkAndDraw = true;
            else if (!((readMove.Peek() == exchangeSymbol) && (savePositions[playerToMove][0][0] % 10 == pawnUnits)))
                return false;

            readMove.Dequeue();
            if (checkAndDraw)
            {
                if (readMove.Peek() != drawSymbol)
                    return false;
                else
                {
                    give = States.Draw;
                    return true;
                }
            }

            exchangeWith = specialFigures.IndexOf(readMove.Peek());
            if (exchangeWith == -1)
                return false;

            exchange = true;
            exchangeWith += figures[playerToMove][0][0] - kingUnits + nightUnits;
            if (readMove.Count == 1)
                return true;

            readMove.Dequeue();
            if (readMove.Count == 1)
            {
                if (readMove.Peek() == checkSymbol)
                    give = States.Check;
                else if (readMove.Peek() == drawSymbol)
                    give = States.Draw;
                else if (readMove.Peek() == checkmateSymbol)
                    give = States.Checkmate;
                else
                    return false;

                return true;
            }

            if (readMove.Peek() != checkSymbol)
                return false;

            readMove.Dequeue();
            if (readMove.Peek() != drawSymbol)
                return false;

            checkAndDraw = true;
            return true;
        }
        else
            return false;

        #endregion
    }

    public static bool IsLegalMove() // Легализация на въведения човешки или от изиграна партия ход 
    {
        #region Resign, Question for draw by agreement, Accept draw by agreement

        if (give == States.Resign)
            return true;

        if ((gotMove == drawQuestion)
                && ((gameMode == GameModes.PlayerVsPlayer) || (gameMode == GameModes.PlayerVsComputer) || (gameMode == GameModes.ComputerVsComputer) || (gameMode == GameModes.FinishGame)))
            return true;

        if (((gotMove == drawByAgreementShort) || (gotMove == drawByAgreement)) 
                && (gameMode == GameModes.CheckMoveList))
            return true;

        #endregion

        #region Direct Draw by Material/Repetition/Fifty-move rule BEFORE move any figure

        if ((gotMove == draw)
                && ((((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                        && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop)))
                    || (3 <= maxMatches)
                    || (50 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer])))
        {
            drawAfterMakeMove = false;
            return true;
        }

        #endregion

        #region Validate figure(s) and fields and eventually move figure(s)

        drawAfterMakeMove = true;

        if (castle != Castles.noCastle)
        {
            if (!CastlePossibility())
                return false;

            savePositions[playerToMove][0][0] = figures[playerToMove][0][0]; // ориентирче единствено за това, че е изпълнена рокада
            makeNextCheck = true;
        }
        else
        {
            //! tuk gyrmi при грешния bxa8=Q, вместо bxa1=Q
            if (((savePositions[playerToMove][0][1] == savePositions[playerToMove][1][1]) && (savePositions[playerToMove][0][2] == savePositions[playerToMove][1][2]))
                    || (battlefield[savePositions[playerToMove][0][1], savePositions[playerToMove][0][2]] != savePositions[playerToMove][0][0])
                        || (!takes && (battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]] != emptyField)))
                return false;

            if (takes 
                && !enPassant 
                && ((battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]] <= figures[oppositePlayer][0][0] - kingUnits) 
                    || (figures[oppositePlayer][0][0] <= battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]])))
                return false;

            //? Отгоре е новия вариант
            //if (takes
            //        && ((battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]] <= figures[oppositePlayer][0][0] - kingUnits)
            //            || (figures[oppositePlayer][0][0] <= battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]])))
            //    return false;

            canJump = true;
            switch (savePositions[playerToMove][0][0] % 10)
            {
                case kingUnits:     { canJump = JumpOfKing(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]); break; }
                case queenUnits:    { canJump = JumpOfQueen(savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]); break; }
                case rookUnits:     { canJump = JumpOfRook(savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]); break; }
                case bishopUnits:   { canJump = JumpOfBishop(savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]); break; }
                case nightUnits:    { canJump = JumpOfNight(savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]); break; }
                case pawnUnits:     { canJump = JumpOfPawn(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2], takes, enPassant, exchange); break; }
                default: break;
            }

            if (!canJump)
                return false;

            savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2]);
            figures[playerToMove][1][savePositions[playerToMove][0][3]] = savePositions[playerToMove][1][1];
            figures[playerToMove][2][savePositions[playerToMove][0][3]] = savePositions[playerToMove][1][2];

            if (takes)
            {
                if (enPassant)
                {
                    if (playerToMove == 0)
                        savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 4, savePositions[playerToMove][1][2]);
                    else
                        savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 3, savePositions[playerToMove][1][2]);
                }
                else
                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                
                materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                takenFigures[oppositePlayer].Add(figures[oppositePlayer][0][savePositions[playerToMove][1][3]]);
                RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);
            }

            if (exchange)
            {
                materials[playerToMove] += exchangeWith - figures[playerToMove][0][savePositions[playerToMove][0][3]];
                figures[playerToMove][0][savePositions[playerToMove][0][3]] = exchangeWith;
                MakeMove(0, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], exchangeWith, savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
            }
            else
            {
                if (enPassant)
                {
                    if (playerToMove == 0)
                    {
                        MakeMove(emptyField, 4, savePositions[playerToMove][0][2], savePositions[playerToMove][0][0], 5, savePositions[playerToMove][1][2]);
                        MakeMove(emptyField, 4, savePositions[playerToMove][1][2], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                    }
                    else
                    {
                        MakeMove(emptyField, 3, savePositions[playerToMove][0][2], savePositions[playerToMove][0][0], 2, savePositions[playerToMove][1][2]);
                        MakeMove(emptyField, 3, savePositions[playerToMove][1][2], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                    }
                }
                else
                    MakeMove(0, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][0][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
            }

            if (gotMove == "Rd3+=")
            //if (gotMove == "Kd6-c6=")
            { }

            willBeUnderCheck = Checks(playerToMove);
            makeNextCheck = !willBeUnderCheck;
            if (makeNextCheck)
            {
                oppositeCheck = Checks(oppositePlayer);
                if (oppositeCheck)
                {
                    if (!((give == States.Check) || (give == States.Checkmate) || checkAndDraw))
                    {
                        makeNextCheck = false;
                        if (gameMode == GameModes.CheckMoveList)
                            urongMove = true;
                    }
                }

                if (checkAndDraw)
                    makeNextCheck = makeNextCheck && oppositeCheck;
            }
        }

        #endregion

        #region Validate anonce AFTER move figure(s)

        if (makeNextCheck)
        {
            #region =Material и +=Material

            if ((give == States.Draw)
                    && ((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                        && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop)))
            {
                drawKind = drawByInsufficientMaterial;
                realState = give;
                return true;
            }

            #endregion

            #region Добавяме заради +=Fifty и +=Repetition

            if (oppositeCheck && give == States.Draw)
            {
                if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук ползвам ориентирчето
                {
                    if (50 <= passiveMoves[oppositePlayer])
                    {
                        if (oppositePlayer == 0)
                            drawKind = drawByWhiteFiftyMoveRule;
                        else
                            drawKind = drawByBlackFiftyMoveRule;

                        realState = give;
                        return true;
                    }
                }
                else
                {
                    SaveCurrentBattlefield(false);

                    if ((3 <= maxMatchesEventually)
                        || (49 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer])) // 49 + текущия == 50 за playerToMove
                    {
                        if (3 <= maxMatchesEventually)
                            drawKind = drawByRepetition;
                        else if (49 <= passiveMoves[playerToMove])
                        {
                            if (playerToMove == 0)
                                drawKind = drawByWhiteFiftyMoveRule;
                            else
                                drawKind = drawByBlackFiftyMoveRule;
                        }
                        else // 50 <= passiveMoves[oppositePlayer]
                        {
                            if (oppositePlayer == 0)
                                drawKind = drawByWhiteFiftyMoveRule;
                            else
                                drawKind = drawByBlackFiftyMoveRule;
                        }

                        maxMatches = maxMatchesEventually; // не е необходимо
                        realState = give;
                        return true;
                    }
                    else // изтриваме последната запазена маса в резултат на и повторенията заедно с недопустимия ход
                    {
                        for (mpilmk = 0; mpilmk <= indexOfCurrentBattlefield; mpilmk++)
                            if (saveBattlefields[mpilmk] == saveBattlefields[indexOfCurrentBattlefield])
                                matches[mpilmk]--;

                        matches.RemoveAt(indexOfCurrentBattlefield);
                        saveBattlefields.RemoveAt(indexOfCurrentBattlefield);

                        makeNextCheck = false;
                    }
                }
            }

            #endregion

            if ((((give == States.Free) || (give == States.Draw)) && oppositeCheck) 
                    || (((give == States.Check) || (give == States.Checkmate)) && !oppositeCheck))
                makeNextCheck = false; //! Стигаше се до тук и не приемаше +=Fifty и +=Repetition   ...   Поправено!!!
            else
            {
                oppositeAvoid = OppositeAvoid();

                #region Checkmate и =Stalemate

                if (!oppositeAvoid)
                {
                    if (give == States.Checkmate)
                    {
                        //? Нарочно не пипаме запазените маси и не реиндексираме влязлата фигура
                        //if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук също ползвам ориентирчето
                        //    ClearAllSavedBattlefields(playerToMove);
                        //else
                        //    SaveCurrentBattlefield(true);

                        //if (exchange)
                        //    FiguresRearrangement(savePositions[playerToMove][0][3]);

                        realState = give;
                        return true;
                    }

                    if (give == States.Draw) // =Stalemate
                    {
                        //? Нарочно не пипаме запазените маси и не реиндексираме влязлата фигура
                        //if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук също ползвам ориентирчето
                        //    ClearAllSavedBattlefields(playerToMove);
                        //else
                        //    SaveCurrentBattlefield(true);

                        //if (exchange)
                        //    FiguresRearrangement(savePositions[playerToMove][0][3]);

                        drawKind = drawByStalemate;

                        realState = give;
                        return true;
                    }
                }

                #endregion

                if (((give == States.Checkmate) && oppositeAvoid)
                        || (((give == States.Free) || (give == States.Check)) && !oppositeAvoid))
                    makeNextCheck = false;

                #region =Fifty СЛЕД и =Repetition ПРЕДИ и СЛЕД хода

                //! a4:b5=(Stalemate и {=?= в режим CheckMoveList}) може, но a4:b5=FMR и a4:b5+=(FMR) е НЕВЪЗМОЖНО! и изобщо специален пат (т.е. oppositeAvoid == true) след ан пасан, т.е. ако enPassant == true, няма смисъл да проверявам
                if ((give == States.Draw) && oppositeAvoid)// && !enPassant) //! ето защо добавям и !enPassant, но май ще го махна заради МуувЛист и средно =
                {
                    if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук ползвам ориентирчето
                    {
                        if (50 <= passiveMoves[oppositePlayer])
                        {
                            if (oppositePlayer == 0)
                                drawKind = drawByWhiteFiftyMoveRule;
                            else
                                drawKind = drawByBlackFiftyMoveRule;

                            realState = give;
                            return true;
                        }
                        else
                            makeNextCheck = false; //! хода завършва с =, остава единствената възможност =?= и то при Четене от лист

                        //! в комбинация с долното и махане на ан пасан-а от условието, е може би като "//! заради средно грешно ="
                        //if (gameMode == GameModes.CheckMoveList && unwantedMove)
                        //    return false;
                    }
                    else
                    {
                        SaveCurrentBattlefield(false);

                        if ((3 <= maxMatchesEventually)
                            || (49 <= passiveMoves[playerToMove]) || (50 <= passiveMoves[oppositePlayer])) // 49 + текущия == 50 за playerToMove, тъй като SaveCurrentBattlefield(FALSE) не увеличава с +1 реалните passiveMoves[playerToMove]
                        {
                            if (3 <= maxMatchesEventually)
                                drawKind = drawByRepetition;
                            else if (49 <= passiveMoves[playerToMove])
                            {
                                if (playerToMove == 0)
                                    drawKind = drawByWhiteFiftyMoveRule;
                                else
                                    drawKind = drawByBlackFiftyMoveRule;
                            }
                            else // 50 <= passiveMoves[oppositePlayer]
                            {
                                if (oppositePlayer == 0)
                                    drawKind = drawByWhiteFiftyMoveRule;
                                else
                                    drawKind = drawByBlackFiftyMoveRule;
                            }

                            maxMatches = maxMatchesEventually; // не е необходимо
                            realState = give;
                            return true;
                        }
                        else // изтриваме последната запазена маса в резултат на недопустим ход
                        {
                            for (mpilmk = 0; mpilmk <= indexOfCurrentBattlefield; mpilmk++)
                                if (saveBattlefields[mpilmk] == saveBattlefields[indexOfCurrentBattlefield])
                                    matches[mpilmk]--;

                            matches.RemoveAt(indexOfCurrentBattlefield);
                            saveBattlefields.RemoveAt(indexOfCurrentBattlefield);

                            makeNextCheck = false;

                            //! в комбинация с горното и махане на ан пасан-а от условието, е може би като "//! заради средно грешно ="
                            //if (gameMode == GameModes.CheckMoveList && unwantedMove)
                            //    return false;
                        }
                    }
                }

                #endregion
            }
        }

        #endregion

        #region Rearrangement figures and save the new one or clear all saved battlefields

        if (makeNextCheck)
        {
            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук също ползвам ориентирчето
                ClearAllSavedBattlefields(playerToMove);
            else
                SaveCurrentBattlefield(true);

            if (exchange)
                FiguresRearrangement(savePositions[playerToMove][0][3]);
        }

        #endregion

        #region САМО за =?= и то САМО в режим CheckMoveList

        //if (gotMove == "a7-a5=")
        //    Thread.Sleep(10);

        //! 
        //if (unwantedMoves && !makeNextCheck && gameMode == GameModes.CheckMoveList && give != States.Checkmate)
        //    return false;

        //! заради средно грешно =
        if (unwantedMoves && makeNextCheck && gameMode == GameModes.CheckMoveList && give == States.Draw)
            return false;

        if (!makeNextCheck
            && gameMode == GameModes.CheckMoveList 
            //&& currentMove == moveList.Count - 1 // може би не е необходимо или изобщо не е за тук
            && give == States.Draw 
            && !urongMove) //? няма никаква възможност за = , освен =?=
        {
            if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук също ползвам ориентирчето
                ClearAllSavedBattlefields(playerToMove);
            else
                SaveCurrentBattlefield(true);

            if (exchange)
                FiguresRearrangement(savePositions[playerToMove][0][3]);

            //SAMO Probno za gre6en sreden =
            //if (currentMove < moveList.Count - 1)
            //    return false;

            gotMove = gotMove.Remove(gotMove.Length - 1);
            moveList[moveList.Count - 1] = gotMove;

            if (oppositeCheck)
                give = States.Check;
            else
                give = States.Free;

            moveList.Add(drawByAgreementShort);

            using (StreamWriter changeReadyMoveList = new StreamWriter("readyMoveList.txt", false, Encoding.GetEncoding("windows-1251")))
            {
                //for (ifml = 0; ifml < moveList.Count - 1; ifml++)
                //    changeReadyMoveList.WriteLine(moveList[ifml]);

                //changeReadyMoveList.Write(moveList[moveList.Count - 1]);

                //! Вместо горното
                changeReadyMoveList.Write(moveList[0].Trim());
                for (ifml = 1; ifml < moveList.Count; ifml++)
                    changeReadyMoveList.Write(string.Format("\r\n{0}", moveList[ifml].Trim()));
            }

            makeNextCheck = true;
        }

        #endregion

        #region Back this invalid move

        if (!makeNextCheck)
        {
            if (castle != Castles.noCastle)
            {
                figures[playerToMove][2][0] = 4;

                if ((castle == Castles.castleKingsideFree) || (castle == Castles.castleKingsideCheck) || (castle == Castles.castleKingsideDraw) || (castle == Castles.castleKingsideCheckmate))
                {
                    MakeMove(0, castleRow, 6, king, castleRow, 4);
                    MakeMove(0, castleRow, 5, king - kingUnits + rookUnits, castleRow, 7);
                    figures[playerToMove][2][indexOfCastleRook] = 7;
                }
                else
                {
                    MakeMove(0, castleRow, 2, king, castleRow, 4);
                    MakeMove(0, castleRow, 3, king - kingUnits + rookUnits, castleRow, 0);
                    figures[playerToMove][2][indexOfCastleRook] = 0;
                }

                castlePossibility[playerToMove][0] = true;
            }
            else
            {
                figures[playerToMove][0][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][0];
                figures[playerToMove][1][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][1];
                figures[playerToMove][2][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][2];

                if (enPassant)
                {
                    if (playerToMove == 0)
                    {
                        MakeMove(savePositions[playerToMove][0][0], 4, savePositions[playerToMove][0][2], emptyField, 5, savePositions[playerToMove][1][2]);
                        MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, savePositions[playerToMove][1][2], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove, който е объркал хода и е казал "ан пасан", подскача на едно място
                    }
                    else
                    {
                        MakeMove(savePositions[playerToMove][0][0], 3, savePositions[playerToMove][0][2], emptyField, 2, savePositions[playerToMove][1][2]);
                        MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, savePositions[playerToMove][1][2], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove, който е объркал хода и е казал "ан пасан", подскача на едно място
                    }
                }
                else
                    MakeMove(savePositions[playerToMove][0][0], savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);

                if (takes)
                {
                    if (enPassant)
                    {
                        if (playerToMove == 0)
                            AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, savePositions[playerToMove][1][2]);
                        else
                            AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, savePositions[playerToMove][1][2]);
                    }
                    else
                        AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);

                    materials[oppositePlayer] += figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                    takenFigures[oppositePlayer].RemoveAt(takenFigures[oppositePlayer].Count - 1);
                }

                if (exchange)
                    materials[playerToMove] -= exchangeWith - figures[playerToMove][0][savePositions[playerToMove][0][3]];
            }
        }

        #endregion

        return makeNextCheck;
    }

    public static void ClearAllSavedBattlefields(int player) // Изчистване на всички записани положения на масата след активен ход 
    {
        saveBattlefields.Clear();
        matches.Clear();
        maxMatches = 0;
        passiveMoves[player] = 0;
    }

    public static void SaveCurrentBattlefield(bool afterRealMove) // Записва положението на масата след пасивен ход (за =Repetition и =Fifty-rule) 
    {
        saveCurrentBattlefield.Clear();
        for (mpscbi = 0; mpscbi <= 7; mpscbi++)
            for (mpscbj = 0; mpscbj <= 7; mpscbj++)
                saveCurrentBattlefield.Append(battlefield[mpscbi, mpscbj]);

        saveBattlefields.Add(saveCurrentBattlefield.ToString());
        indexOfCurrentBattlefield = saveBattlefields.Count - 1;
        matches.Add(1);
        for (mpscbk = 0; mpscbk < indexOfCurrentBattlefield; mpscbk++)
            if (saveBattlefields[mpscbk] == saveBattlefields[indexOfCurrentBattlefield])
            {
                matches[mpscbk]++;
                matches[indexOfCurrentBattlefield]++;
            }

        maxMatchesEventually = maxMatches;
        if (afterRealMove)
        {
            if (maxMatches < matches[indexOfCurrentBattlefield])
                maxMatches = matches[indexOfCurrentBattlefield];

            //! Според мен, passiveMoves[playerToMove]++ трябва да се повишава САМО след направен доказано позволен ход, т.е. само при afterRealMove == true
            passiveMoves[playerToMove]++;
        }
        else
        {
            if (maxMatchesEventually < matches[indexOfCurrentBattlefield])
                maxMatchesEventually = matches[indexOfCurrentBattlefield];
        }

        //! Според мен, passiveMoves[playerToMove]++ трябва да се повишава САМО след направен доказано позволен ход, т.е. само при afterRealMove == true
        //passiveMoves[playerToMove]++;
    }

        #region Castle / Рокада

    public static bool CastlePossibility() // Проверява за възможна рокада и я ПРАВИ 
    {
        if (realState != States.Free)
            return false;

        if (!castlePossibility[playerToMove][0])
            return false;

        king = figures[playerToMove][0][0];
        if (playerToMove == 0)
            castleRow = 0;
        else
            castleRow = 7;

        if ((castle == Castles.castleKingsideFree) || (castle == Castles.castleKingsideCheck) || (castle == Castles.castleKingsideDraw) || (castle == Castles.castleKingsideCheckAndDraw) || (castle == Castles.castleKingsideCheckmate))
        {
            if (!(castlePossibility[playerToMove][1] && castlePossibility[playerToMove][2]))
                return false;

            if ((battlefield[castleRow, 5] != 0) || (battlefield[castleRow, 6] != 0))
                return false;

            MakeMove(0, castleRow, 4, king, castleRow, 5);
            figures[playerToMove][2][0] = 5;
            if (Checks(playerToMove))
            {
                MakeMove(0, castleRow, 5, king, castleRow, 4);
                figures[playerToMove][2][0] = 4;
                return false;
            }

            MakeMove(0, castleRow, 5, king, castleRow, 6);
            figures[playerToMove][2][0] = 6;
            if (Checks(playerToMove))
            {
                MakeMove(0, castleRow, 6, king, castleRow, 4);
                figures[playerToMove][2][0] = 4;
                return false;
            }

            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 7);
            MakeMove(0, castleRow, 7, king - kingUnits + rookUnits, castleRow, 5); 
            figures[playerToMove][2][indexOfCastleRook] = 5;

            if (castle == Castles.castleKingsideCheckAndDraw)
                if (!Checks(oppositePlayer))
                {
                    MakeMove(0, castleRow, 6, king, castleRow, 4);
                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 5, king - kingUnits + rookUnits, castleRow, 7);
                    figures[playerToMove][2][indexOfCastleRook] = 7;
                    return false;
                }

            castlePossibility[playerToMove][0] = false;
        }
        else
        {
            if (!(castlePossibility[playerToMove][1] && castlePossibility[playerToMove][3]))
                return false;

            if ((battlefield[castleRow, 3] != 0) || (battlefield[castleRow, 2] != 0) || (battlefield[castleRow, 1] != 0))
                return false;

            MakeMove(0, castleRow, 4, king, castleRow, 3);
            figures[playerToMove][2][0] = 3;
            if (Checks(playerToMove))
            {
                MakeMove(0, castleRow, 3, king, castleRow, 4);
                figures[playerToMove][2][0] = 4;
                return false;
            }

            MakeMove(0, castleRow, 3, king, castleRow, 2);
            figures[playerToMove][2][0] = 2;
            if (Checks(playerToMove))
            {
                MakeMove(0, castleRow, 2, king, castleRow, 4);
                figures[playerToMove][2][0] = 4;
                return false;
            }

            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 0);
            MakeMove(0, castleRow, 0, king - kingUnits + rookUnits, castleRow, 3);
            figures[playerToMove][2][indexOfCastleRook] = 3;

            if (castle == Castles.castleQueensideCheckAndDraw)
                if (!Checks(oppositePlayer))
                {
                    MakeMove(0, castleRow, 2, king, castleRow, 4);
                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 3, king - kingUnits + rookUnits, castleRow, 0);
                    figures[playerToMove][2][indexOfCastleRook] = 0;
                    return false;
                }

            castlePossibility[playerToMove][0] = false;
        }

        return true;
    }

    public static void AddCastleRestrictions() // Добавя ограничения за бъдеща рокада 
    {
        if (castlePossibility[0][0])
        {
            if (battlefield[0, 4] != whiteKing)
                castlePossibility[0][0] = false;
            else
            {
                if (battlefield[0, 7] != whiteRook)
                    castlePossibility[0][2] = false;

                if (battlefield[0, 0] != whiteRook)
                    castlePossibility[0][3] = false;

                if (!castlePossibility[0][2] && !castlePossibility[0][3])
                    castlePossibility[0][0] = false;
            }
        }

        if (castlePossibility[1][0])
        {
            if (battlefield[7, 4] != blackKing)
                castlePossibility[1][0] = false;
            else
            {
                if (battlefield[7, 7] != blackRook)
                    castlePossibility[1][2] = false;

                if (battlefield[7, 0] != blackRook)
                    castlePossibility[1][3] = false;

                if (!castlePossibility[1][2] && !castlePossibility[1][3])
                    castlePossibility[1][0] = false;
            }
        }
    }

        #endregion

    public static int ReturnIndexOfFigure(int player, int onRow, int onColumn) // Връща индекса на фигура 
    {
        for (rif = 0; rif < figures[player][0].Count; rif++)
            if ((figures[player][1][rif] == onRow) && (figures[player][2][rif] == onColumn))
                return rif;

        return -1;
    }

        #region Jumps / Скокове

    public static bool JumpOfKing(int player, int fromRow, int fromColumn, int toRow, int toColumn)
    {
        if ((-1 <= toRow - fromRow) && (toRow - fromRow <= 1) && (-1 <= toColumn - fromColumn) && (toColumn - fromColumn <= 1)
                && ((toRow - figures[1 - player][1][0] < -1) || (1 < toRow - figures[1 - player][1][0]) || (toColumn - figures[1 - player][2][0] < -1) || (1 < toColumn - figures[1 - player][2][0])))
            return true;
        else
            return false;
    }

    public static bool JumpOfQueen(int fromRow, int fromColumn, int toRow, int toColumn)
    {
        return (JumpOfRook(fromRow, fromColumn, toRow, toColumn) || JumpOfBishop(fromRow, fromColumn, toRow, toColumn));
    }

    public static bool JumpOfRook(int fromRow, int fromColumn, int toRow, int toColumn)
    {
        if (toRow == fromRow)
        {
            if (toColumn < fromColumn)
            {
                for (jrj = toColumn + 1; jrj < fromColumn; jrj++)
                    if (battlefield[toRow, jrj] != 0)
                        return false;
            }
            else
                for (jrj = fromColumn + 1; jrj < toColumn; jrj++)
                    if (battlefield[toRow, jrj] != 0)
                        return false;
        }
        else if (toColumn == fromColumn)
        {
            if (toRow < fromRow)
            {
                for (jri = toRow + 1; jri < fromRow; jri++)
                    if (battlefield[jri, toColumn] != 0)
                        return false;
            }
            else
                for (jri = fromRow + 1; jri < toRow; jri++)
                    if (battlefield[jri, toColumn] != 0)
                        return false;
        }
        else
            return false;

        return true;
    }

    public static bool JumpOfBishop(int fromRow, int fromColumn, int toRow, int toColumn)
    {
        if ((toRow == fromRow) || (toColumn == fromColumn))
            return false;

        if ((int)Math.Abs(toRow - fromRow) != (int)Math.Abs(toColumn - fromColumn))
            return false;

        columnChange = 1;
        if (toRow < fromRow)
        {
            if (toColumn > fromColumn)
                columnChange = -1;

            for (jbi = toRow + 1; jbi < fromRow; jbi++)
                if (battlefield[jbi, toColumn + (jbi - toRow) * columnChange] != 0)
                    return false;
        }
        else
        {
            if (toColumn < fromColumn)
                columnChange = -1;

            for (jbi = fromRow + 1; jbi < toRow; jbi++)
                if (battlefield[jbi, fromColumn + (jbi - fromRow) * columnChange] != 0)
                    return false;
        }

        return true;
    }

    public static bool JumpOfNight(int fromRow, int fromColumn, int toRow, int toColumn)
    {
        if (((toRow == fromRow - 2) && (toColumn == fromColumn - 1))
            || ((toRow == fromRow - 2) && (toColumn == fromColumn + 1))
            || ((toRow == fromRow - 1) && (toColumn == fromColumn - 2))
            || ((toRow == fromRow - 1) && (toColumn == fromColumn + 2))
            || ((toRow == fromRow + 1) && (toColumn == fromColumn - 2))
            || ((toRow == fromRow + 1) && (toColumn == fromColumn + 2))
            || ((toRow == fromRow + 2) && (toColumn == fromColumn - 1))
            || ((toRow == fromRow + 2) && (toColumn == fromColumn + 1)))
            return true;
        else
            return false;
    }

    public static bool JumpOfPawn(int player, int fromR, int fromColumn, int toRow, int toColumn, bool taking = false, bool passant = false, bool exchanging = false)
    {
        if (passant)
        {
            //! ЗАДЪЛЖИТЕЛНО е lastMoves[oppositePlayer] вече да съществува (иначе трябва проверката lastMoves[oppositePlayer].Exists)
            if (lastMoves[oppositePlayer].Count < 1)
                return false;

            if (battlefield[toRow, toColumn] != emptyField)
                return false;

            if (playerToMove == 0)
            {
                if ((fromR != 4) || (toRow != 5))
                    return false;

                if (battlefield[4, toColumn] != figures[oppositePlayer][0][0] - kingUnits + pawnUnits)
                    return false;

                if ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}{2}{3}{4}", (char)(49 + toColumn), 7, moveSymbol, (char)(49 + toColumn), 5)) == 0)
                    || ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}", (char)(49 + toColumn), 5)) == 0)
                        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(moveSymbol) == -1)
                        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(takeSymbol) == -1)))
                    return false;

                //if ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}{2}{3}{4}", (char)(49 + toColumn), 7, moveSymbol, (char)(49 + toColumn), 5)) == 0)
                //    || ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}", (char)(49 + toColumn), 5)) == 0)
                //        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(moveSymbol) == -1)    
                //        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(takeSymbol) == -1)))
                //    return false;
            }
            else // playerToMove == 1
            {
                if ((fromR != 3) || (toRow != 2))
                    return false;

                if (battlefield[3, toColumn] != figures[oppositePlayer][0][0] - kingUnits + pawnUnits)
                    return false;

                if ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}{2}{3}{4}", (char)(49 + toColumn), 2, moveSymbol, (char)(49 + toColumn), 4)) == 0)
                    || ((lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(string.Format("{0}{1}", (char)(49 + toColumn), 4)) == 0)
                        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(moveSymbol) == -1)
                        && (lastMoves[oppositePlayer][lastMoves[oppositePlayer].Count - 1].IndexOf(moveSymbol) == -1)))
                    return false;
            }
        }

        if ((toRow == fromR) || (toColumn - fromColumn < -1) || (1 < toColumn - fromColumn) || (toRow - fromR < -2) || (2 < toRow - fromR))
            return false;

        if (taking && ((toColumn == fromColumn) || (toRow - fromR == 2) || (toRow - fromR == -2)))
            return false;

        if (!taking && (toColumn != fromColumn))
            return false;

        if (player == 0)
        {
            if (toRow < fromR)
                return false;

            if ((toRow - fromR == 2) && (toColumn != fromColumn))
                return false;

            if ((fromR != 1) && (toRow - fromR == 2))
                return false;

            if ((toRow - fromR == 2) && (battlefield[fromR + 1, fromColumn] != emptyField))
                return false;

            if (exchanging && (toRow < 7))
                return false;

            if ((toRow == 7) && !exchanging)
                return false;
        }
        else // playerToMove == 1
        {
            if (toRow > fromR)
                return false;

            if ((fromR - toRow == 2) && (toColumn != fromColumn))
                return false;

            if ((fromR != 6) && (fromR - toRow == 2))
                return false;

            if ((fromR - toRow == 2) && (battlefield[fromR - 1, fromColumn] != emptyField))
                return false;

            if (exchanging && (0 < toRow))
                return false;

            if ((toRow == 0) && !exchanging)
                return false;
        }

        return true;
    }

        #endregion

        #region Talking / Изговаряне

    public static string MakeSentence() // Създава изречението 
    {
        sentence.Clear();
        if (urongMove)
        {
            sentence.Append(urongMoveNote);
            return sentence.ToString();
        }

        if (unwantedMove)
        {
            sentence.Append(unwantedMoveNote);
            return sentence.ToString();
        }

        if (playerToMove == 0)
            sentence.Append("White ");
        else
            sentence.Append("Black ");

        if (give == States.Resign)
            sentence.Append("- Resigns!");
        else if ((gotMove == drawQuestion)
                    && ((gameMode == GameModes.PlayerVsPlayer) || (gameMode == GameModes.PlayerVsComputer) || (gameMode == GameModes.ComputerVsComputer)))
            sentence.Append("- wants Draw?");
        else if ((gotMove == drawByAgreementShort) || (gotMove == drawByAgreement))
        {
            sentence.Clear();
            if (playerToMove == 0)
                sentence.Append("Black - accepts draw - by agreement!");
            else
                sentence.Append("White - accepts draw - by agreement!");
        }
        else
        {
            if (drawAfterMakeMove)
            {
                if (castle != Castles.noCastle)
                {
                    if ((castle == Castles.castleKingsideFree) || (castle == Castles.castleKingsideCheck) || (castle == Castles.castleKingsideDraw) || (castle == Castles.castleKingsideCheckmate))
                        sentence.Append("makes castle kingside");
                    else
                        sentence.Append("makes castle queenside");
                }
                else
                {
                    switch (savePositions[playerToMove][0][0] % 10)
                    {
                        case kingUnits: { sentence.Append("king"); break; }
                        case queenUnits: { sentence.Append("queen"); break; }
                        case rookUnits: { sentence.Append("rook"); break; }
                        case bishopUnits: { sentence.Append("bishop"); break; }
                        case nightUnits: { sentence.Append("night"); break; }
                        case pawnUnits: { sentence.Append("pawn"); break; }
                        default: break;
                    }

                    sentence.Append(" on " + (char)(savePositions[playerToMove][0][2] + 97));
                    sentence.Append(" " + (savePositions[playerToMove][0][1] + 1));
                    if (takes)
                    {
                        sentence.Append(" takes");
                        sentence.Append(playerToMove == 0 ? " black " : " white ");
                        switch ((savePositions[playerToMove][1][0] + 
                            ((enPassant 
                                && (gameMode == GameModes.CheckMoveList 
                                    || gameMode == GameModes.PlayerVsPlayer 
                                    || (gameMode == GameModes.PlayerVsComputer && playerToMove == playWith))) ? pawnUnits : 0)) % 10)
                        {
                            //case kingUnits: { sentence.Append("king"); break; }
                            case queenUnits: { sentence.Append("queen"); break; }
                            case rookUnits: { sentence.Append("rook"); break; }
                            case bishopUnits: { sentence.Append("bishop"); break; }
                            case nightUnits: { sentence.Append("night"); break; }
                            case pawnUnits: { sentence.Append("pawn"); break; }
                            default: break;
                        }

                        sentence.Append(" on");
                    }
                    else
                        sentence.Append(" moves to");

                    sentence.Append(" " + (char)(97 + savePositions[playerToMove][1][2]));
                    if (enPassant)
                    {
                        sentence.Append(" " + (1 + savePositions[playerToMove][1][1] + ((gameMode == GameModes.ComputerVsComputer || (gameMode == GameModes.PlayerVsComputer && playerToMove != playWith)) ? (playerToMove == 0 ? 1 : -1) : 0)));
                        sentence.Append(" - en passant");
                    }
                    else
                        sentence.Append(" " + (1 + savePositions[playerToMove][1][1]));

                    if (exchange)
                    {
                        sentence.Append(" and exchanges with ");
                        switch (exchangeWith % 10)
                        {
                            //case kingUnits: { sentence.Append("king"); break; }
                            case queenUnits: { sentence.Append("queen"); break; }
                            case rookUnits: { sentence.Append("rook"); break; }
                            case bishopUnits: { sentence.Append("bishop"); break; }
                            case nightUnits: { sentence.Append("night"); break; }
                            case pawnUnits: { sentence.Append("pawn"); break; }
                            default: break;
                        }
                    }
                }
            }

            switch (give)
            {
                case States.Free: { sentence.Append("."); break; }
                case States.Check: { sentence.Append(" - Check!"); break; }
                case States.Draw:
                    {
                        if (gotMove.IndexOf(checkSymbol) != -1)
                            sentence.Append(" - Check! and ");

                        if ((drawKind != drawByStalemate) && (drawKind != drawByInsufficientMaterial))
                        {
                            if (drawAfterMakeMove && gotMove.IndexOf(checkSymbol) == -1)
                                sentence.Append("- and ");

                            sentence.Append("announces - ");
                        }
                        else
                        {
                            if (drawAfterMakeMove)
                                sentence.Append("- and ");

                            sentence.Append("announces automatic - ");
                        }

                        if (drawKind == drawByWhiteFiftyMoveRule)
                            sentence.Append("- Draw - by white fifty-move rule!");
                        else if (drawKind == drawByBlackFiftyMoveRule)
                            sentence.Append("- Draw - by black fifty-move rule!");
                        else if (drawKind == drawByRepetition)
                            sentence.Append("- Draw - by repetition!");
                        else if (drawKind == drawByInsufficientMaterial)
                            sentence.Append("- Draw - by insufficient material!");
                        else if (drawKind == drawByStalemate)
                            sentence.Append("- Draw - by stalemate!");

                        break;
                    }
                case States.Checkmate: { sentence.Append(" - Checkmate!"); break; }
                default: break;
            }
        }

        return sentence.ToString();
    }

    public static void SayMove(string sayThis) // Изговаря изречението 
    {
        using (say = new SpeechSynthesizer())
        {
            say.SetOutputToDefaultAudioDevice();
            say.Rate = 0;
            //say.Volume = 100;
            say.Speak(sayThis);
        }
    }

        #endregion

    #endregion

    #region Make move

    public static void MakeMove(int fromFigure, int fromRow, int fromColumn, int toFigure, int toRow, int toColumn) // Променя САМО масата 
    {
        battlefield[fromRow, fromColumn] = fromFigure;
        battlefield[toRow, toColumn] = toFigure;
    }

    #endregion

    #region Check for check / Проверка за шах

    public static bool Checks(int player) // Проверява дали на играч е даден шах 
    {
        oppositeKing = figures[1 - player][0][0];
        kingRow = figures[player][1][0];
        kingColumn = figures[player][2][0];

        #region Queen and Rook

        for (theRow = kingRow - 1; 0 <= theRow; theRow--)
            if (battlefield[theRow, kingColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, kingColumn] == kingUnits - queenUnits)
                        || (oppositeKing - battlefield[theRow, kingColumn] == kingUnits - rookUnits))
                    return true;

                break;
            }

        for (theRow = kingRow + 1; theRow <= 7; theRow++)
            if (battlefield[theRow, kingColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, kingColumn] == kingUnits - queenUnits)
                        || (oppositeKing - battlefield[theRow, kingColumn] == kingUnits - rookUnits))
                    return true;

                break;
            }

        for (theColumn = kingColumn - 1; 0 <= theColumn; theColumn--)
            if (battlefield[kingRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[kingRow, theColumn] == kingUnits - queenUnits)
                        || (oppositeKing - battlefield[kingRow, theColumn] == kingUnits - rookUnits))
                    return true;

                break;
            }

        for (theColumn = kingColumn + 1; theColumn <= 7; theColumn++)
            if (battlefield[kingRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[kingRow, theColumn] == kingUnits - queenUnits)
                        || (oppositeKing - battlefield[kingRow, theColumn] == kingUnits - rookUnits))
                    return true;

                break;
            }

        #endregion

        #region Queen and Bishop

        theColumn = kingColumn;
        columnChange = -1;
        for (theRow = kingRow - 1; 0 <= theRow; theRow--)
        {
            theColumn += columnChange;
            if (theColumn < 0)
                break;

            if (battlefield[theRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, theColumn] == kingUnits - queenUnits)
                    || (oppositeKing - battlefield[theRow, theColumn] == kingUnits - bishopUnits))
                    return true;

                break;
            }
        }

        theColumn = kingColumn;
        columnChange = 1;
        for (theRow = kingRow - 1; 0 <= theRow; theRow--)
        {
            theColumn += columnChange;
            if (7 < theColumn)
                break;

            if (battlefield[theRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, theColumn] == kingUnits - queenUnits)
                    || (oppositeKing - battlefield[theRow, theColumn] == kingUnits - bishopUnits))
                    return true;

                break;
            }
        }

        theColumn = kingColumn;
        columnChange = -1;
        for (theRow = kingRow + 1; theRow <= 7; theRow++)
        {
            theColumn += columnChange;
            if (theColumn < 0)
                break;

            if (battlefield[theRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, theColumn] == kingUnits - queenUnits)
                    || (oppositeKing - battlefield[theRow, theColumn] == kingUnits - bishopUnits))
                    return true;

                break;
            }
        }

        theColumn = kingColumn;
        columnChange = 1;
        for (theRow = kingRow + 1; theRow <= 7; theRow++)
        {
            theColumn += columnChange;
            if (7 < theColumn)
                break;

            if (battlefield[theRow, theColumn] != 0)
            {
                if ((oppositeKing - battlefield[theRow, theColumn] == kingUnits - queenUnits)
                    || (oppositeKing - battlefield[theRow, theColumn] == kingUnits - bishopUnits))
                    return true;

                break;
            }
        }

        #endregion

        #region Night

        if ((0 <= kingRow - 2) && (0 <= kingColumn - 1) && (oppositeKing - battlefield[kingRow - 2, kingColumn - 1] == kingUnits - nightUnits))
            return true;

        if ((0 <= kingRow - 1) && (0 <= kingColumn - 2) && (oppositeKing - battlefield[kingRow - 1, kingColumn - 2] == kingUnits - nightUnits))
            return true;

        if ((kingRow + 1 <= 7) && (0 <= kingColumn - 2) && (oppositeKing - battlefield[kingRow + 1, kingColumn - 2] == kingUnits - nightUnits))
            return true;

        if ((kingRow + 2 <= 7) && (0 <= kingColumn - 1) && (oppositeKing - battlefield[kingRow + 2, kingColumn - 1] == kingUnits - nightUnits))
            return true;

        if ((kingRow + 2 <= 7) && (kingColumn + 1 <= 7) && (oppositeKing - battlefield[kingRow + 2, kingColumn + 1] == kingUnits - nightUnits))
            return true;

        if ((kingRow + 1 <= 7) && (kingColumn + 2 <= 7) && (oppositeKing - battlefield[kingRow + 1, kingColumn + 2] == kingUnits - nightUnits))
            return true;

        if ((0 <= kingRow - 1) && (kingColumn + 2 <= 7) && (oppositeKing - battlefield[kingRow - 1, kingColumn + 2] == kingUnits - nightUnits))
            return true;

        if ((0 <= kingRow - 2) && (kingColumn + 1 <= 7) && (oppositeKing - battlefield[kingRow - 2, kingColumn + 1] == kingUnits - nightUnits))
            return true;

        #endregion

        #region Pawn

        if (battlefield[kingRow, kingColumn] == whiteDecimals + kingUnits)
        {
            if ((kingRow + 1 <= 7) && (0 <= kingColumn - 1) && (oppositeKing - battlefield[kingRow + 1, kingColumn - 1] == kingUnits - pawnUnits))
                return true;

            if ((kingRow + 1 <= 7) && (kingColumn + 1 <= 7) && (oppositeKing - battlefield[kingRow + 1, kingColumn + 1] == kingUnits - pawnUnits))
                return true;
        }
        else
        {
            if ((0 <= kingRow - 1) && (0 <= kingColumn - 1) && (oppositeKing - battlefield[kingRow - 1, kingColumn - 1] == kingUnits - pawnUnits))
                return true;

            if ((0 <= kingRow - 1) && (kingColumn + 1 <= 7) && (oppositeKing - battlefield[kingRow - 1, kingColumn + 1] == kingUnits - pawnUnits))
                return true;
        }

        #endregion

        return false;
    }

    #endregion

    #region Opposite's Chance / 

    public static bool OppositeAvoid()
    {
        for (figureIndex = 0; figureIndex < figures[oppositePlayer][0].Count; figureIndex++)
        {
            ClearAllFieldsForLooking();
            if (IsThereLegalMoveThisFigure())
                return true;
        }

        return false;
    }

    public static bool IsThereLegalMoveThisFigure()
    {
        SaveOppositePositionsWithoutRealTakes(oppositePlayer, 0, figures[oppositePlayer][0][figureIndex], figures[oppositePlayer][1][figureIndex], figures[oppositePlayer][2][figureIndex]);

        king = figures[playerToMove][0][0];
        oppositeKing = figures[oppositePlayer][0][0];

        thisKing = oppositeKing;
        otherKing = king;

        figureRow = savePositions[oppositePlayer][0][1];
        figureColumn = savePositions[oppositePlayer][0][2];

        switch (figures[oppositePlayer][0][figureIndex] % 10)
        {
            case kingUnits:     return LegalMovesThisKing(true);
            case queenUnits:    return LegalMovesThisQueen(true);
            case rookUnits:     return LegalMovesThisRook(true);
            case bishopUnits:   return LegalMovesThisBishop(true);
            case nightUnits:    return LegalMovesThisNight(true);
            case pawnUnits:     return LegalMovesThisPawn(true);
            default:            return false;
        }
    }

    #endregion

    #region Legal moves on this figure

    public static bool LegalMovesThisKing(bool stopAtFirstMeeting)
    {
        if (stopAtFirstMeeting)
        {
            KingMovement(playerToMove);
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveThisKing(oppositePlayer, toThisField))
                    return true;
        }
        else
        {
            KingMovement(oppositePlayer);
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveThisKing(playerToMove, toThisField))
                    AddPossibleMove();
        }

        return false;
    }

    public static bool LegalMovesThisQueen(bool stopAtFirstMeeting)
    {
        QeenMovement();
        if (stopAtFirstMeeting)
        {
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(oppositePlayer, toThisField))
                    return true;
        }
        else
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(playerToMove, toThisField))
                    AddPossibleMove();

        return false;
    }

    public static bool LegalMovesThisRook(bool stopAtFirstMeeting)
    {
        RookMovement();
        if (stopAtFirstMeeting)
        {
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(oppositePlayer, toThisField))
                    return true;
        }
        else
        {
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(playerToMove, toThisField))
                    AddPossibleMove();
        }

        return false;
    }

    public static bool LegalMovesThisBishop(bool stopAtFirstMeeting)
    {
        BishopMovement();
        if (stopAtFirstMeeting)
        {
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(oppositePlayer, toThisField))
                    return true;
        }
        else
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(playerToMove, toThisField))
                    AddPossibleMove();

        return false;
    }

    public static bool LegalMovesThisNight(bool stopAtFirstMeeting)
    {
        NightMovement();
        if (stopAtFirstMeeting)
        {
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(oppositePlayer, toThisField))
                    return true;
        }
        else
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(playerToMove, toThisField))
                    AddPossibleMove();

        return false;
    }

    public static bool LegalMovesThisPawn(bool stopAtFirstMeeting)
    {
        if (stopAtFirstMeeting)
        {
            PawnMovement(oppositePlayer);
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(oppositePlayer, toThisField))
                    return true;
        }
        else
        {
            PawnMovement(playerToMove);
            for (toThisField = 0; toThisField < lookOnlyThisPositions[0].Count; toThisField++)
                if (TryMakeMoveNotKing(playerToMove, toThisField))
                    AddPossibleMove();
        }

        return false;
    }

    public static bool TryMakeMoveThisKing(int player, int toThisField)
    {
        SaveOppositePositionsWithoutRealTakes(player, 1, lookOnlyThisPositions[0][toThisField], lookOnlyThisPositions[1][toThisField], lookOnlyThisPositions[2][toThisField]);
        figures[player][1][0] = savePositions[player][1][1];
        figures[player][2][0] = savePositions[player][1][2];
        MakeMove(0, savePositions[player][0][1], savePositions[player][0][2], savePositions[player][0][0], savePositions[player][1][1], savePositions[player][1][2]);
        willBeUnderCheck = Checks(player);
        figures[player][1][0] = savePositions[player][0][1];
        figures[player][2][0] = savePositions[player][0][2];
        MakeMove(savePositions[player][0][0], savePositions[player][0][1], savePositions[player][0][2], savePositions[player][1][0], savePositions[player][1][1], savePositions[player][1][2]);
        return !willBeUnderCheck;
    }

    public static bool TryMakeMoveNotKing(int player, int toThisField)
    {
        SaveOppositePositionsWithoutRealTakes(player, 1, lookOnlyThisPositions[0][toThisField], lookOnlyThisPositions[1][toThisField], lookOnlyThisPositions[2][toThisField]);
        MakeMove(0, savePositions[player][0][1], savePositions[player][0][2], savePositions[player][0][0], savePositions[player][1][1], savePositions[player][1][2]);
        willBeUnderCheck = Checks(player);
        MakeMove(savePositions[player][0][0], savePositions[player][0][1], savePositions[player][0][2], savePositions[player][1][0], savePositions[player][1][1], savePositions[player][1][2]);
        return !willBeUnderCheck;
    }

    public static void SaveOppositePositionsWithoutRealTakes(int player, int fromOrTo, int figure, int row, int column)
    {
        savePositions[player][fromOrTo][0] = figure;
        savePositions[player][fromOrTo][1] = row;
        savePositions[player][fromOrTo][2] = column;
    }

    #endregion

    #region Movements / Движения

    public static void KingMovement(int player)
    {
        kingRow = figures[player][1][0];
        kingColumn = figures[player][2][0];
        for (rowChange = -1; rowChange <= 1; rowChange++)
            for (columnChange = -1; columnChange <= 1; columnChange++)
                if (!((rowChange == 0) && (columnChange == 0)))
                {
                    rowMovement = figureRow + rowChange;
                    columnMovement = figureColumn + columnChange;
                    if ((0 <= rowMovement) && (rowMovement <= 7) && (0 <= columnMovement) && (columnMovement <= 7))
                    {
                        theField = battlefield[rowMovement, columnMovement];
                        if (((theField <= thisKing - kingUnits) || (thisKing < theField))
                                && (theField != otherKing)
                                    && ((rowMovement - kingRow < -1) || (1 < rowMovement - kingRow) || (columnMovement - kingColumn < -1) || (1 < columnMovement - kingColumn)))
                            AddFieldForLooking(theField, rowMovement, columnMovement);
                    }
                }
    }

    public static void QeenMovement()
    {
        RookMovement();
        BishopMovement();
    }

    public static void RookMovement()
    {
        rowMovement = figureRow;
        for (columnMovement = figureColumn - 1; 0 <= columnMovement; columnMovement--)
        {
            theField = battlefield[rowMovement, columnMovement];
            if (theField == 0)
                AddFieldForLooking(theField, rowMovement, columnMovement);
            else
            {
                if ((otherKing - kingUnits < theField) && (theField < otherKing))
                    AddFieldForLooking(theField, rowMovement, columnMovement);

                break;
            }
        }

        for (columnMovement = figureColumn + 1; columnMovement <= 7; columnMovement++)
        {
            theField = battlefield[rowMovement, columnMovement];
            if (theField == 0)
                AddFieldForLooking(theField, rowMovement, columnMovement);
            else
            {
                if ((otherKing - kingUnits < theField) && (theField < otherKing))
                    AddFieldForLooking(theField, rowMovement, columnMovement);

                break;
            }
        }

        columnMovement = figureColumn;
        for (rowMovement = figureRow - 1; 0 <= rowMovement; rowMovement--)
        {
            theField = battlefield[rowMovement, columnMovement];
            if (theField == 0)
                AddFieldForLooking(theField, rowMovement, columnMovement);
            else
            {
                if ((otherKing - kingUnits < theField) && (theField < otherKing))
                    AddFieldForLooking(theField, rowMovement, columnMovement);

                break;
            }
        }

        for (rowMovement = figureRow + 1; rowMovement <= 7; rowMovement++)
        {
            theField = battlefield[rowMovement, columnMovement];
            if (theField == 0)
                AddFieldForLooking(theField, rowMovement, columnMovement);
            else
            {
                if ((otherKing - kingUnits < theField) && (theField < otherKing))
                    AddFieldForLooking(theField, rowMovement, columnMovement);

                break;
            }
        }
    }

    public static void BishopMovement()
    {
        BishopMovementAdding(-1, -1);
        BishopMovementAdding(-1, 1);
        BishopMovementAdding(1, -1);
        BishopMovementAdding(1, 1);
    }

    public static void BishopMovementAdding(int rChange, int cChange)
    {
        columnMovement = figureColumn;
        for (rowMovement = figureRow + rChange; (0 <= rowMovement) && (rowMovement <= 7); rowMovement += rChange)
        {
            columnMovement += cChange;
            if ((0 <= columnMovement) && (columnMovement <= 7))
            {
                theField = battlefield[rowMovement, columnMovement];
                if (theField == 0)
                    AddFieldForLooking(theField, rowMovement, columnMovement);
                else
                {
                    if ((otherKing - kingUnits < theField) && (theField < otherKing))
                        AddFieldForLooking(theField, rowMovement, columnMovement);

                    break;
                }
            }
            else
                break;
        }
    }

    public static void NightMovement()
    {
        NightMovementAdding(figureRow - 2, figureColumn - 1);
        NightMovementAdding(figureRow - 2, figureColumn + 1);
        NightMovementAdding(figureRow - 1, figureColumn - 2);
        NightMovementAdding(figureRow - 1, figureColumn + 2);
        NightMovementAdding(figureRow + 1, figureColumn - 2);
        NightMovementAdding(figureRow + 1, figureColumn + 2);
        NightMovementAdding(figureRow + 2, figureColumn - 1);
        NightMovementAdding(figureRow + 2, figureColumn + 1);
    }

    public static void NightMovementAdding(int rMovement, int cMovement)
    {
        if ((0 <= rMovement) && (rMovement <= 7) && (0 <= cMovement) && (cMovement <= 7))
        {
            theField = battlefield[rMovement, cMovement];
            if (((theField <= thisKing - kingUnits) || (thisKing < theField))
                    && (theField != otherKing))
                AddFieldForLooking(theField, rMovement, cMovement);
        }
    }

    public static void PawnMovement(int player)
    {
        if (player == 0)
            rowChange = 1;
        else
            rowChange = -1;

        rowMovement = figureRow + rowChange;
        if ((0 <= rowMovement) && (rowMovement <= 7))
            for (columnChange = -1; columnChange <= 1; columnChange++)
            {
                columnMovement = figureColumn + columnChange;
                if ((0 <= columnMovement) && (columnMovement <= 7))
                {
                    theField = battlefield[rowMovement, columnMovement];
                    if (columnMovement != figureColumn)
                    {
                        if ((otherKing - kingUnits < theField) && (theField < otherKing))
                            AddFieldForLooking(theField, rowMovement, columnMovement);
                    }
                    else
                    {
                        if (theField == 0)
                        {
                            AddFieldForLooking(theField, rowMovement, columnMovement);
                            if (((player == 0) && (figureRow == 1)) || ((player == 1) && (figureRow == 6)))
                            {
                                rowMovement += rowChange;
                                theField = battlefield[rowMovement, columnMovement];
                                if (theField == 0)
                                    AddFieldForLooking(theField, rowMovement, columnMovement);

                                rowMovement -= rowChange;
                            }
                        }
                    }
                }
            }
    }

    #endregion

    #region Looking array

    public static void ClearAllFieldsForLooking()
    {
        lookOnlyThisPositions[0].Clear();
        lookOnlyThisPositions[1].Clear();
        lookOnlyThisPositions[2].Clear();
    }

    public static void AddFieldForLooking(int figure, int row, int column)
    {
        lookOnlyThisPositions[0].Add(figure);
        lookOnlyThisPositions[1].Add(row);
        lookOnlyThisPositions[2].Add(column);
    }

    #endregion

    #region Artificial Intelligence / Изкуствен интелект

    public static void FindAllPossibleMoves() // Намира всички възможни ходове на текущия playerToMove играч (НЕ само на този който наистина е на ход) 
    {
        #region Fill all non-special possible moves on player to move

        ClearAllPossibleMoves();
        for (figureIndex = 0; figureIndex < figures[playerToMove][0].Count; figureIndex++)
        {
            ClearAllFieldsForLooking();

            possibleMoves[playerToMove].Add(new List<List<int>>());
            possibleMoves[playerToMove][figureIndex].Add(new List<int>() { figureIndex, figures[playerToMove][0][figureIndex], figures[playerToMove][1][figureIndex], figures[playerToMove][2][figureIndex] });

            SaveOppositePositionsWithoutRealTakes(playerToMove, 0, figures[playerToMove][0][figureIndex], figures[playerToMove][1][figureIndex], figures[playerToMove][2][figureIndex]);
            savePositions[playerToMove][0][3] = figureIndex;

            king = figures[playerToMove][0][0];
            oppositeKing = figures[oppositePlayer][0][0];

            figureRow = savePositions[playerToMove][0][1];
            figureColumn = savePositions[playerToMove][0][2];

            thisKing = king;
            otherKing = oppositeKing;

            switch (figures[playerToMove][0][figureIndex] % 10)
            {
                case kingUnits:     { LegalMovesThisKing(false);    break; }
                case queenUnits:    { LegalMovesThisQueen(false);   break; }
                case rookUnits:     { LegalMovesThisRook(false);    break; }
                case bishopUnits:   { LegalMovesThisBishop(false);  break; }
                case nightUnits:    { LegalMovesThisNight(false);   break; }
                case pawnUnits:     { LegalMovesThisPawn(false);    break; }
                default: break;
            }
        }

        for (aifapmr = possibleMoves[playerToMove].Count - 1; 0 <= aifapmr; aifapmr--)
            if (possibleMoves[playerToMove][aifapmr].Count < 2)
                possibleMoves[playerToMove].RemoveAt(aifapmr);

        #endregion

        #region Add Castles (if it possible)

        if (!Checks(playerToMove) && castlePossibility[playerToMove][0])
        {
            castling[playerToMove][0] = false;
            castling[playerToMove][1] = false;

            king = figures[playerToMove][0][0];
            if (playerToMove == 0)
                castleRow = 0;
            else
                castleRow = 7;

            if (castlePossibility[playerToMove][1] && castlePossibility[playerToMove][2] && (battlefield[castleRow, 5] == 0) && (battlefield[castleRow, 6] == 0) 
                && (battlefield[castleRow, 7] == figures[playerToMove][0][0] - kingUnits + rookUnits))
            {
                figures[playerToMove][2][0] = 5;
                MakeMove(0, castleRow, 4, king, castleRow, 5);
                if (Checks(playerToMove))
                {
                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 5, king, castleRow, 4);
                }
                else
                {
                    figures[playerToMove][2][0] = 6;
                    MakeMove(0, castleRow, 5, king, castleRow, 6);
                    if (!Checks(playerToMove))
                    {
                        castling[playerToMove][0] = true;
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 17, 17, 17, 17 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 17, 17, 17, 17 });
                    }

                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 6, king, castleRow, 4);
                }
            }

            if (castlePossibility[playerToMove][1] && castlePossibility[playerToMove][3] && (battlefield[castleRow, 3] == 0) && (battlefield[castleRow, 2] == 0) && (battlefield[castleRow, 1] == 0)
                && (battlefield[castleRow, 0] == figures[playerToMove][0][0] - kingUnits + rookUnits))
            {
                figures[playerToMove][2][0] = 3;
                MakeMove(0, castleRow, 4, king, castleRow, 3);
                if (Checks(playerToMove))
                {
                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 3, king, castleRow, 4);
                }
                else
                {
                    figures[playerToMove][2][0] = 2;
                    MakeMove(0, castleRow, 3, king, castleRow, 2);
                    if (!Checks(playerToMove))
                    {
                        castling[playerToMove][1] = true;
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 18, 18, 18, 18 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 18, 18, 18, 18 });
                    }

                    figures[playerToMove][2][0] = 4;
                    MakeMove(0, castleRow, 2, king, castleRow, 4);
                }
            }
        }

        #endregion

        #region Add En Passant

        if (0 <= enPassantPreparing)
        {
            if (playerToMove == 0)
            {
                if (0 < enPassantPreparing 
                    && battlefield[4, enPassantPreparing - 1] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, 4, enPassantPreparing - 1);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 5;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing;

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 4, enPassantPreparing);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, 4, enPassantPreparing - 1, figures[playerToMove][0][0] - kingUnits + pawnUnits, 5, enPassantPreparing);
                    MakeMove(emptyField, 4, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място

                    if (!Checks(playerToMove))
                    {
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[playerToMove][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing - 1 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing });
                    }

                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 4;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing - 1;

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing);

                    MakeMove(figures[playerToMove][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing - 1, emptyField, 5, enPassantPreparing);
                    MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }

                if (enPassantPreparing < 7 
                    && battlefield[4, enPassantPreparing + 1] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, 4, enPassantPreparing + 1);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 5;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing;

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 4, enPassantPreparing);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, 4, enPassantPreparing + 1, figures[playerToMove][0][0] - kingUnits + pawnUnits, 5, enPassantPreparing);
                    MakeMove(emptyField, 4, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място

                    if (!Checks(playerToMove))
                    {
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[playerToMove][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing + 1 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing });
                    }

                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 4;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing + 1;

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing);

                    MakeMove(figures[playerToMove][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing + 1, emptyField, 5, enPassantPreparing);
                    MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 4, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
            }
            else // playerToMove == 1
            {
                if (0 < enPassantPreparing
                    && battlefield[3, enPassantPreparing - 1] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, 3, enPassantPreparing - 1);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 2;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing;

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 3, enPassantPreparing);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, 3, enPassantPreparing - 1, figures[playerToMove][0][0] - kingUnits + pawnUnits, 2, enPassantPreparing);
                    MakeMove(emptyField, 3, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място

                    if (!Checks(playerToMove))
                    {
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[playerToMove][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing - 1 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing });
                    }

                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 3;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing - 1;

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing);

                    MakeMove(figures[playerToMove][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing - 1, emptyField, 2, enPassantPreparing);
                    MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }

                if (enPassantPreparing < 7
                    && battlefield[3, enPassantPreparing + 1] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, 3, enPassantPreparing + 1);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 2;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing;

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, 3, enPassantPreparing);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, 3, enPassantPreparing + 1, figures[playerToMove][0][0] - kingUnits + pawnUnits, 2, enPassantPreparing);
                    MakeMove(emptyField, 3, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място

                    if (!Checks(playerToMove))
                    {
                        possibleMoves[playerToMove].Add(new List<List<int>>());
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[playerToMove][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing + 1 });
                        possibleMoves[playerToMove][possibleMoves[playerToMove].Count - 1].Add(new List<int>() { 19, figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing });
                    }

                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = 3;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = enPassantPreparing + 1;

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing);

                    MakeMove(figures[playerToMove][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing + 1, emptyField, 2, enPassantPreparing);
                    MakeMove(figures[oppositePlayer][0][0] - kingUnits + pawnUnits, 3, enPassantPreparing, figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
            }
        }

        #endregion

        #region Count all possible moves

        allPossibleMoves[playerToMove] = 0;
        for (aifapm = 0; aifapm < possibleMoves[playerToMove].Count; aifapm++)
            allPossibleMoves[playerToMove] += possibleMoves[playerToMove][aifapm].Count - 1;

        #endregion
    }

    public static void ClearAllPossibleMoves() // Изпразва масива с възможните ходове на текущия playerToMove играч (НЕ само на този който наистина е на ход) 
    {
        possibleMoves[playerToMove].Clear();
    }

    public static void AddPossibleMove() // Добавя възможен ход 
    {
        possibleMoves[playerToMove][figureIndex].Add(new List<int>() { figureIndex, savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2] });
    }

    public static void ChoosePossibleMove() // Избира следващия компютърен ход 
    {
        #region Избор на ход

        if (gameBothDifficulty[playerToMove] != Difficulty.Amateur) // Търсене на перфектен ход (# или =)
            CheckForMateInOne();
        else
        {
            //! Закоментирам ги САМО за да проверя дали работи ан пасан
            randomIndexOfPerfectFigure = randomGenerator.Next(0, possibleMoves[playerToMove].Count);
            randomOnePerfectMoveOfThisPerfectFigure = randomGenerator.Next(1, possibleMoves[playerToMove][randomIndexOfPerfectFigure].Count);

            //! До края е само за тестове върху ан пасан
            //bool foundEnPassant = false;
            //for (int findFirstEnPassant = 0; findFirstEnPassant < possibleMoves[playerToMove].Count; findFirstEnPassant++)
            //    if (possibleMoves[playerToMove][findFirstEnPassant][0][0] == 19)
            //    {
            //        foundEnPassant = true;
            //        randomIndexOfPerfectFigure = findFirstEnPassant;
            //        randomOnePerfectMoveOfThisPerfectFigure = 1;
            //    }

            //if (!foundEnPassant)
            //{
                //randomIndexOfPerfectFigure = randomGenerator.Next(0, possibleMoves[playerToMove].Count);
                //randomOnePerfectMoveOfThisPerfectFigure = randomGenerator.Next(1, possibleMoves[playerToMove][randomIndexOfPerfectFigure].Count);
            //}
        }

        #endregion

        castled = false;

        #region Ан Пасан

        if (18 < possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
        {
            savePositions[playerToMove][0][0] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1];
            savePositions[playerToMove][0][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
            savePositions[playerToMove][0][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];
            savePositions[playerToMove][1][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            savePositions[playerToMove][1][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];
            savePositions[playerToMove][1][0] = figures[playerToMove][0][0] - kingUnits + pawnUnits; // possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1]

            takes = true;
            exchange = false;

            enPassant = true;

            if (playerToMove == 0)
            {
                savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3]);
                figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1;
                figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];

                savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                takenFigures[oppositePlayer].Add(figures[oppositePlayer][0][savePositions[playerToMove][1][3]]);
                RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
            }
            else
            {
                savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3]);
                figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] - 1;
                figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];

                savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                takenFigures[oppositePlayer].Add(figures[oppositePlayer][0][savePositions[playerToMove][1][3]]);
                RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] - 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
            }

            //! това не би дало на другия да продължи бройката до = Fifty, НО не е необходимо, тъй като и предишния и този ход са с пешка!!!
            ClearAllSavedBattlefields(playerToMove);
        }

        #endregion

        #region Рокада

        else if (16 < possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
        {
            takes = false;
            exchange = false;

            castled = true;

            king = figures[playerToMove][0][0];
            if (playerToMove == 0)
                castleRow = 0;
            else
                castleRow = 7;

            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] == 17)
            {
                figures[playerToMove][2][0] = 6; 
                MakeMove(0, castleRow, 4, king, castleRow, 6);
                indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 7);
                figures[playerToMove][2][indexOfCastleRook] = 5;
                MakeMove(0, castleRow, 7, king - kingUnits + rookUnits, castleRow, 5);
            }
            else // == 18
            {
                figures[playerToMove][2][0] = 2;
                MakeMove(0, castleRow, 4, king, castleRow, 2);
                indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 0);
                figures[playerToMove][2][indexOfCastleRook] = 3;
                MakeMove(0, castleRow, 0, king - kingUnits + rookUnits, castleRow, 3);
            }

            SaveCurrentBattlefield(true);
        }

        #endregion

        #region Обикновен ход

        else
        {
            savePositions[playerToMove][0][0] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1];
            savePositions[playerToMove][0][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
            savePositions[playerToMove][0][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];
            savePositions[playerToMove][1][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            savePositions[playerToMove][1][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];
            savePositions[playerToMove][1][0] = battlefield[savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]];

            #region How many figures can jump

            if (computerNotationCurrent == Notation.ShortAlgebraic)
            {
                shortAlgebraicHowManyFiguresCanJump = 0;

                for (aicpmhmfcj = 0; aicpmhmfcj < figures[playerToMove][0].Count; aicpmhmfcj++)
                {
                    if (figures[playerToMove][0][aicpmhmfcj] == savePositions[playerToMove][0][0])
                    {
                        switch (figures[playerToMove][0][aicpmhmfcj] % 10)
                        {
                            case queenUnits:
                                {
                                    if (JumpOfQueen(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                    {
                                        MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        if (!Checks(playerToMove))
                                            shortAlgebraicHowManyFiguresCanJump++;

                                        MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                    }

                                    break;
                                }
                            case rookUnits:
                                {
                                    if (JumpOfRook(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                    {
                                        MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        if (!Checks(playerToMove))
                                            shortAlgebraicHowManyFiguresCanJump++;

                                        MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                    }

                                    break;
                                }
                            case bishopUnits:
                                {
                                    if (JumpOfBishop(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                    {
                                        MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        if (!Checks(playerToMove))
                                            shortAlgebraicHowManyFiguresCanJump++;

                                        MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                    }

                                    break;
                                }
                            case nightUnits:
                                {
                                    if (JumpOfNight(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                    {
                                        MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        if (!Checks(playerToMove))
                                            shortAlgebraicHowManyFiguresCanJump++;

                                        MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                    }

                                    break;
                                }
                            default: break;
                        }
                    }
                }

                if (1 == shortAlgebraicHowManyFiguresCanJump)
                    shortAlgebraicHowManyFiguresCanJump = 0; //! Don't show row and column
                else // 1 < shortAlgebraicHowManyFiguresCanJump
                {
                    shortAlgebraicHowManyFiguresCanJump = 0;

                    for (aicpmhmfcj = 0; aicpmhmfcj < figures[playerToMove][0].Count; aicpmhmfcj++)
                    {
                        if (figures[playerToMove][0][aicpmhmfcj] == savePositions[playerToMove][0][0] && figures[playerToMove][2][aicpmhmfcj] == savePositions[playerToMove][0][2])
                        {
                            switch (figures[playerToMove][0][aicpmhmfcj] % 10)
                            {
                                case queenUnits:
                                    {
                                        if (JumpOfQueen(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                        {
                                            MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            if (!Checks(playerToMove))
                                                shortAlgebraicHowManyFiguresCanJump++;

                                            MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        }

                                        break;
                                    }
                                case rookUnits:
                                    {
                                        if (JumpOfRook(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                        {
                                            MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            if (!Checks(playerToMove))
                                                shortAlgebraicHowManyFiguresCanJump++;

                                            MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        }

                                        break;
                                    }
                                case bishopUnits:
                                    {
                                        if (JumpOfBishop(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                        {
                                            MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            if (!Checks(playerToMove))
                                                shortAlgebraicHowManyFiguresCanJump++;

                                            MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        }

                                        break;
                                    }
                                case nightUnits:
                                    {
                                        if (JumpOfNight(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                        {
                                            MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            if (!Checks(playerToMove))
                                                shortAlgebraicHowManyFiguresCanJump++;

                                            MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                        }

                                        break;
                                    }
                                default: break;
                            }
                        }
                    }

                    if (1 < shortAlgebraicHowManyFiguresCanJump) //! ELSE IF   1 == shortAlgebraicHowManyFiguresCanJump show ONLY Column
                    {
                        shortAlgebraicHowManyFiguresCanJump = 0;

                        for (aicpmhmfcj = 0; aicpmhmfcj < figures[playerToMove][0].Count; aicpmhmfcj++)
                        {
                            if (figures[playerToMove][0][aicpmhmfcj] == savePositions[playerToMove][0][0] && figures[playerToMove][1][aicpmhmfcj] == savePositions[playerToMove][0][1])
                            {
                                switch (figures[playerToMove][0][aicpmhmfcj] % 10)
                                {
                                    case queenUnits:
                                        {
                                            if (JumpOfQueen(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case rookUnits:
                                        {
                                            if (JumpOfRook(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case bishopUnits:
                                        {
                                            if (JumpOfBishop(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    case nightUnits:
                                        {
                                            if (JumpOfNight(figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]))
                                            {
                                                MakeMove(emptyField, figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], figures[playerToMove][0][aicpmhmfcj], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                                if (!Checks(playerToMove))
                                                    shortAlgebraicHowManyFiguresCanJump++;

                                                MakeMove(figures[playerToMove][0][aicpmhmfcj], figures[playerToMove][1][aicpmhmfcj], figures[playerToMove][2][aicpmhmfcj], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                                            }

                                            break;
                                        }
                                    default: break;
                                }
                            }
                        }

                        if (1 == shortAlgebraicHowManyFiguresCanJump)
                            shortAlgebraicHowManyFiguresCanJump = 2; //! show ONLY Row
                        else
                            shortAlgebraicHowManyFiguresCanJump = 3; //! show Row and Column
                    }
                }
            }

            #endregion

            takes = false;
            exchange = false;

            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1] != 0)
            {
                takes = true;
                savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                takenFigures[oppositePlayer].Add(figures[oppositePlayer][0][savePositions[playerToMove][1][3]]);
                RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);
            }

            MakeMove(0, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
            figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            figures[playerToMove][2][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];
            
            if ((figures[playerToMove][0][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                && (((playerToMove == 0) && (figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == 7))
                    || ((playerToMove == 1) && (figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == 0))))
            {
                exchange = true;

                // izpolzvame eventualno dannite ot additional intellect s kakvo se zamenq pe6kata - Q ili N za perfekten hod (# ili =)
                if (gameBothDifficulty[playerToMove] != Difficulty.Amateur)
                    switch (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][5])
                    {
                        case 0: { exchangeWith = figures[playerToMove][0][0] - kingUnits + queenUnits; break; }
                        case 1: { exchangeWith = figures[playerToMove][0][0] - kingUnits + nightUnits; break; }
                        default: break;
                    }
                else
                    exchangeWith = randomGenerator.Next(figures[playerToMove][0][0] - kingUnits + pawnUnits + 1, figures[playerToMove][0][0]);

                battlefield[possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]] = exchangeWith;
                figures[playerToMove][0][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = exchangeWith;
                materials[playerToMove] += exchangeWith - (figures[playerToMove][0][0] - kingUnits) - pawnUnits;

                //MyError();
            }

            if ((figures[playerToMove][0][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] % 10 == pawnUnits) || takes)
                ClearAllSavedBattlefields(playerToMove);
            else
                SaveCurrentBattlefield(true);

            if (exchange)
                FiguresRearrangement(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]);
        }
        #endregion

        #region Анонс

        if (Checks(oppositePlayer))
        {
            if (OppositeAvoid())
                give = States.Check;
            else
                give = States.Checkmate;
        }
        else
        {
            if (OppositeAvoid())
                give = States.Free;
            else
            {
                give = States.Draw;
                drawKind = drawByStalemate;
            }
        }

        #endregion

        #region Вид на рокадата

        if (castled)
        {
            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] == 17)
            {
                if (give == States.Free)
                    castle = Castles.castleKingsideFree;
                else if (give == States.Check)
                    castle = Castles.castleKingsideCheck;
                else if (give == States.Draw)
                    castle = Castles.castleKingsideDraw;
                else if (give == States.Checkmate) // излишна проверка (ако няма възможност за Resign веднага след рокада (изобщо направен ход))
                    castle = Castles.castleKingsideCheckmate;
                //? Проверката дали рокадата не е castle = castleKingsideCheckAndDraw е в BuildTextOfMove()
            }
            else
            {
                if (give == States.Free)
                    castle = Castles.castleQueensideFree;
                else if (give == States.Check)
                    castle = Castles.castleQueensideCheck;
                else if (give == States.Draw)
                    castle = Castles.castleQueensideDraw;
                else if (give == States.Checkmate) // излишна проверка (ако няма възможност за Resign веднага след рокада (изобщо направен ход))
                    castle = Castles.castleQueensideCheckmate;
                //? Проверката дали рокадата не е castle = castleQueensideCheckAndDraw е в BuildTextOfMove()
            }
        }

        #endregion

        #region Създаване на хода

        BuildTextOfMove();

        #endregion
    }

    public static void CheckForMateInOne() // Проверява за мат в един ход 
    {
        maxGoodMoveOfAllFigures = 0; // отначало перфектната фигура е първата

        for (aicfmioi = 0; aicfmioi < possibleMoves[playerToMove].Count; aicfmioi++)
        {
            for (aicfmioj = 1; aicfmioj < possibleMoves[playerToMove][aicfmioi].Count; aicfmioj++)
            {
                takes = false;
                exchange = false;

                possibleMoves[playerToMove][aicfmioi][aicfmioj].Add(0);

                #region Рокада и Ан Пасан

                if (16 < possibleMoves[playerToMove][aicfmioi][aicfmioj][0])
                {
                    #region Рокада

                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19)
                    {
                        king = figures[playerToMove][0][0];
                        if (playerToMove == 0)
                            castleRow = 0;
                        else
                            castleRow = 7;

                        if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] == 17)
                        {
                            figures[playerToMove][2][0] = 6;
                            MakeMove(0, castleRow, 4, king, castleRow, 6);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 7);
                            figures[playerToMove][2][indexOfCastleRook] = 5;
                            MakeMove(0, castleRow, 7, king - kingUnits + rookUnits, castleRow, 5);
                        }
                        else // == 18
                        {
                            figures[playerToMove][2][0] = 2;
                            MakeMove(0, castleRow, 4, king, castleRow, 2);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 0);
                            figures[playerToMove][2][indexOfCastleRook] = 3;
                            MakeMove(0, castleRow, 0, king - kingUnits + rookUnits, castleRow, 3);
                        }

                        // долния ред по принцип е breakpoint
                        savePositions[playerToMove][0][0] = figures[playerToMove][0][0]; // единствено като ориентир за по следващата проверка, че е играна рокада, т.е. ход за ++repetitionDraw и ++fiftyDraw
                    }

                    #endregion

                    #region Ан Пасан

                    else //! En Passant -> possibleMoves[playerToMove][aicfmioi][aicfmioj][0] == 19
                    {
                        //takes = true; // не ни трябва

                        if (playerToMove == 0)
                        {
                            savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3]);
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1;
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                            savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                        else
                        {
                            savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3]);
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1;
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                            savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                    }

                    #endregion
                }

                #endregion

                #region Обикновен ход

                #region Eвентуално влиза царица

                else
                {
                    savePositions[playerToMove][0][0] = possibleMoves[playerToMove][aicfmioi][0][1];
                    savePositions[playerToMove][0][1] = possibleMoves[playerToMove][aicfmioi][0][2];
                    savePositions[playerToMove][0][2] = possibleMoves[playerToMove][aicfmioi][0][3];
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2]);

                    savePositions[playerToMove][1][0] = possibleMoves[playerToMove][aicfmioi][aicfmioj][1];
                    savePositions[playerToMove][1][1] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2];
                    savePositions[playerToMove][1][2] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][1] != 0)
                    {
                        takes = true;
                        savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                        materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]]; // savePositions[playerToMove][1][0];
                        RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);
                    }

                    MakeMove(0, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                    figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2];
                    figures[playerToMove][2][possibleMoves[playerToMove][aicfmioi][0][0]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];
                    
                    if ((figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                        && (((playerToMove == 0) && (figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] == 7))
                            || ((playerToMove == 1) && (figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] == 0))))
                    {
                        exchange = true;
                        exchangeWith = figures[playerToMove][0][0] - kingUnits + queenUnits;
                        battlefield[possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]] = exchangeWith;
                        figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] = exchangeWith;
                        materials[playerToMove] += queenUnits - pawnUnits;

                        possibleMoves[playerToMove][aicfmioi][aicfmioj].Add(0); // [5] = 0 == Queen
                    }
                }

                    #endregion

                    #region Обикновена проверка за анонса СЛЕД хода

                if (Checks(oppositePlayer))
                {
                    if (OppositeAvoid())
                        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 1;
                    else
                        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 3;
                }
                else
                {
                    if (OppositeAvoid())
                        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 0;
                    else
                        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2; // САМО Stalemate
                }

                    #endregion

                    #region Проверка за Repetition, Material и Fifty СЛЕД хода

                if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19)
                {
                    if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук ползвам ориентира от по-горе в кода // май ще трябва да се освободи от тази проверка и тя да замине надолу в отрицание
                    {
                        //if (takes) // закоментирах го за проба дали може и без него, тъй като може на преден ход или още в началото на този Random-а да е подминал Material ???
                        if (((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                                && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop))
                            || (50 <= passiveMoves[oppositePlayer])) // добавих за проба дали мястото му е тук ??? отново ако Random е подминал Fifty(на истинския oppositePlayer)
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2; // Material и Fifty(на истинския oppositePlayer)
                    }
                    else
                    {
                        saveCurrentBattlefield.Clear();
                        for (aicfmioscbi = 0; aicfmioscbi <= 7; aicfmioscbi++)
                            for (aicfmioscbj = 0; aicfmioscbj <= 7; aicfmioscbj++)
                                saveCurrentBattlefield.Append(battlefield[aicfmioscbi, aicfmioscbj]);

                        currentBattlefield = saveCurrentBattlefield.ToString();
                        maxRepetitionWithCurrentBattlefield = 1; // беше 0, но с текущия би станала 1
                        for (aicfmioscbk = 0; aicfmioscbk < saveBattlefields.Count; aicfmioscbk++)
                            if (saveBattlefields[aicfmioscbk] == currentBattlefield)
                                maxRepetitionWithCurrentBattlefield++;

                        // евентуалната промяна на maxRepetitionWithCurrentBattlefield я добавям за проба дали е наистина за тук ??? - изтърваване при Random
                        if (maxRepetitionWithCurrentBattlefield < maxMatches)
                            maxRepetitionWithCurrentBattlefield = maxMatches;

                        if ((3 <= maxRepetitionWithCurrentBattlefield)
                                || (49 <= passiveMoves[playerToMove]) // с текущия биха станали с 1 повече, т.е. не по-малко от 50
                                || (50 <= passiveMoves[oppositePlayer])) // ако не е играна пешка или не е взета фигура, отново ако Random е подминал Fifty(на истинския oppositePlayer)
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2; // Repetition, Material и Fifty(и на двамата)
                    }
                }

                    #endregion

                    #region Eвентуално влиза кон

                if (exchange)
                {
                    exchangeWith = figures[playerToMove][0][0] - kingUnits + nightUnits;
                    //FullPrint(); // само за тестове
                    battlefield[possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]] = exchangeWith;
                    figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] = exchangeWith;
                    materials[playerToMove] -= queenUnits - nightUnits;

                        #region Надграждаща обикновена проверка за анонса СЛЕД хода

                    if (Checks(oppositePlayer))
                    {
                        if (OppositeAvoid())
                        {
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 1)
                            {
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 1;
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1; // ve4e sme izvadili (zamenili 0 == Queen s) 1 == Night
                            }
                        }
                        else
                        {
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 3) // НЕУМЕСТНО избираме винаги в позиция Checkmate да заменяме пешка с =Q
                            {
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 3;
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            }
                        }
                    }
                    else
                    {
                        if (OppositeAvoid())
                        {
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 0) // НЕУМЕСТНО избираме винаги в позиция Free да заменяме пешка с =Q
                            {
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 0;
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            }
                        }
                        else
                        {
                            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                            {
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2; // САМО Stalemate
                                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            }
                        }
                    }

                        #endregion

                        #region Проверка за Material и Fifty СЛЕД хода

                    //if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // винаги е true !
                    //{
                        //if (takes)
                            if (((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                                    && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop))
                                    || (50 <= passiveMoves[oppositePlayer])) // на истинския oppositePlayer
                                if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                                {
                                    possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                                    possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                                }
                    //}
                    //else
                    //{
                            //saveCurrentBattlefield.Clear();
                            //for (aicfmioscbi = 0; aicfmioscbi <= 7; aicfmioscbi++)
                            //    for (aicfmioscbj = 0; aicfmioscbj <= 7; aicfmioscbj++)
                            //        saveCurrentBattlefield.Append(battlefield[aicfmioscbi, aicfmioscbj]);

                            //currentBattlefield = saveCurrentBattlefield.ToString();
                            //maxRepetitionWithCurrentBattlefield = 0;
                            //for (aicfmioscbk = 0; aicfmioscbk < saveBattlefields.Count; aicfmioscbk++)
                            //    if (saveBattlefields[aicfmioscbk] == currentBattlefield)
                            //        maxRepetitionWithCurrentBattlefield++;

                            //if ((3 <= maxRepetitionWithCurrentBattlefield) // ima exchange, zna4i sme igrali pe6ka, zna4i nqma nov zapis za repetition i fifty-move, zna4i proverqvame samo stariq
                            //        || (50 <= passiveMoves[playerToMove])) // (daje bi trqbvalo da dobavim proverka za fifty i na oppositePlayer, no nie sme q napravili o6te predi da tyrsim vyzmojnite hodove)
                            //    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                            //    {
                            //        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                            //        possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            //    }
                    //}
                }

                        #endregion

                    #endregion

                #endregion

                #region Връщаме изиграния ход назад

                    #region Ан Пасан

                if (18 < possibleMoves[playerToMove][aicfmioi][aicfmioj][0])
                {
                    if (playerToMove == 0)
                    {
                        figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][2];
                        figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][3];

                        AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);

                        MakeMove(possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                        MakeMove(possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                    }
                    else
                    {
                        figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][2];
                        figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][3];

                        AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);

                        MakeMove(possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                        MakeMove(possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                    }
                }

                    #endregion

                    #region Рокада

                else if (16 < possibleMoves[playerToMove][aicfmioi][aicfmioj][0])
                {
                    king = figures[playerToMove][0][0];
                    if (playerToMove == 0)
                        castleRow = 0;
                    else
                        castleRow = 7;

                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] == 17)
                    {
                        figures[playerToMove][2][0] = 4;
                        MakeMove(king, castleRow, 4, 0, castleRow, 6);
                        indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 5);
                        figures[playerToMove][2][indexOfCastleRook] = 7;
                        MakeMove(king - kingUnits + rookUnits, castleRow, 7, 0, castleRow, 5);
                    }
                    else
                    {
                        figures[playerToMove][2][0] = 4;
                        MakeMove(king, castleRow, 4, 0, castleRow, 2);
                        indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 3);
                        figures[playerToMove][2][indexOfCastleRook] = 0;
                        MakeMove(king - kingUnits + rookUnits, castleRow, 0, 0, castleRow, 3);
                    }
                }

                    #endregion

                    #region Обикновен ход

                else
                {
                    figures[playerToMove][0][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][0];
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][1];
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][2];
                    MakeMove(savePositions[playerToMove][0][0], savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                    if (takes)
                    {
                        AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                        materials[oppositePlayer] += figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                    }

                    if (exchange)
                        materials[playerToMove] -= nightUnits - pawnUnits; // последно сме проверявали с Night
                }

                    #endregion

                #endregion
            }

            #region Намираме първия най-добър ход на разглежданата фигура

            maxGoodMoveOfCurrentFigure = possibleMoves[playerToMove][aicfmioi][1][4];
            maxGoodMoveOfCurrentFigureIndex = 1;
            for (crossMovesOfCurrentFigure = 2; crossMovesOfCurrentFigure < possibleMoves[playerToMove][aicfmioi].Count; crossMovesOfCurrentFigure++)
                if (maxGoodMoveOfCurrentFigure < possibleMoves[playerToMove][aicfmioi][crossMovesOfCurrentFigure][4])
                {
                    maxGoodMoveOfCurrentFigure = possibleMoves[playerToMove][aicfmioi][crossMovesOfCurrentFigure][4];
                    maxGoodMoveOfCurrentFigureIndex = crossMovesOfCurrentFigure;
                }

            possibleMoves[playerToMove][aicfmioi][0].Add(maxGoodMoveOfCurrentFigure);
            possibleMoves[playerToMove][aicfmioi][0].Add(maxGoodMoveOfCurrentFigureIndex);

            #endregion

            #region 'Накрая' намираме първата перфектна фигура

            if (maxGoodMoveOfAllFigures < maxGoodMoveOfCurrentFigure)
                maxGoodMoveOfAllFigures = maxGoodMoveOfCurrentFigure;

            #endregion
        }

        #region Aко няма възможен Checkmate или Draw в един ход, а на ход е Nightmare, избираме ход, след който няма да попадне под мат в един ход

        if ((maxGoodMoveOfAllFigures < 2) && (gameBothDifficulty[playerToMove] == Difficulty.Nightmare))
        {
            // за да избера по произволен начин измежду всички ходове (които водят до Free или най-много до Check)
            AddAllCandidates();
            candidateFigures = candidates.Count; // по принцип е breakpoint

            // измежду всички възможни ходове на истинския playerToMove
            for (aicfmioapm = 0; aicfmioapm < allPossibleMoves[playerToMove]; aicfmioapm++)
            {
                // вземаме произволна фигура
                randomIndexOfPerfectFigure = randomGenerator.Next(0, candidateFigures);
                countToRightIndex = 0;
                for (aicfmioriopf = 0; aicfmioriopf < candidates.Count; aicfmioriopf++)
                    if (0 < candidates[aicfmioriopf][0]) // possibleMoves[playerToMove][aicfmioriopf][0][4]
                        if (countToRightIndex == randomIndexOfPerfectFigure)
                        {
                            randomIndexOfPerfectFigure = aicfmioriopf;
                            break;
                        }
                        else
                            countToRightIndex++;

                // избираме произволен ход на вече взетата фигура
                randomOnePerfectMoveOfThisPerfectFigure = randomGenerator.Next(0, candidates[randomIndexOfPerfectFigure][0]);
                countToRightIndex = 0;
                for (aicfmioropmotpf = 1; aicfmioropmotpf < candidates[randomIndexOfPerfectFigure].Count; aicfmioropmotpf++)
                    if (0 < candidates[randomIndexOfPerfectFigure][aicfmioropmotpf]) // possibleMoves[playerToMove][randomIndexOfPerfectFigure][aicfmioropmotpf][4]
                        if (countToRightIndex == randomOnePerfectMoveOfThisPerfectFigure)
                        {
                            randomOnePerfectMoveOfThisPerfectFigure = aicfmioropmotpf;
                            break;
                        }
                        else
                            countToRightIndex++;

                // проверяваме дали след избрания ход истинския playerToMove няма да попадне под мат в един ход
                if (AvoidMateInOne())
                    return;
                else
                {
                    candidates[randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure] = 0;
                    candidates[randomIndexOfPerfectFigure][0]--;
                    if (candidates[randomIndexOfPerfectFigure][0] == 0)
                        candidateFigures--;
                }
            }

            return;
        }

        #endregion

        #region Избираме перфектен ход (# или =)

        // намираме перфектна фигура (с най-висок възможен показател)
        perfectFigure = possibleMoves[playerToMove][0][0][4];
        for (crossFigures = 1; crossFigures < possibleMoves[playerToMove].Count; crossFigures++)
            if (perfectFigure < possibleMoves[playerToMove][crossFigures][0][4])
                perfectFigure = possibleMoves[playerToMove][crossFigures][0][4];

        // преброяваме всички перфектни фигури
        howManyPerfectFigures = 0;
        for (crossFigures = 0; crossFigures < possibleMoves[playerToMove].Count; crossFigures++)
            if (possibleMoves[playerToMove][crossFigures][0][4] == perfectFigure)
                howManyPerfectFigures++;

        // избираме една от всички перфектни фигури
        randomIndexOfPerfectFigure = randomGenerator.Next(0, howManyPerfectFigures);
        countToRightIndex = 0;
        for (countToRightPerfectFigure = 0; countToRightPerfectFigure < possibleMoves[playerToMove].Count; countToRightPerfectFigure++)
            if (possibleMoves[playerToMove][countToRightPerfectFigure][0][4] == perfectFigure)
                if (countToRightIndex == randomIndexOfPerfectFigure)
                {
                    randomIndexOfPerfectFigure = countToRightPerfectFigure;
                    break;
                }
                else
                    countToRightIndex++;

        // преброяваме всички перфектни ходове на вече избраната перфектна фигура
        howManyPerfectMovesOfThisPerfectFigure = 0;
        for (crossMovesOfCurrentFigure = 1; crossMovesOfCurrentFigure < possibleMoves[playerToMove][randomIndexOfPerfectFigure].Count; crossMovesOfCurrentFigure++)
            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][crossMovesOfCurrentFigure][4] == possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][4])
                howManyPerfectMovesOfThisPerfectFigure++;

        // избираме един от всички перфектни ходове на вече избраната перфектна фигура
        randomOnePerfectMoveOfThisPerfectFigure = randomGenerator.Next(0, howManyPerfectMovesOfThisPerfectFigure);
        countToRightIndex = 0;
        for (crossMovesOfCurrentFigure = 1; crossMovesOfCurrentFigure < possibleMoves[playerToMove][randomIndexOfPerfectFigure].Count; crossMovesOfCurrentFigure++)
            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][crossMovesOfCurrentFigure][4] == possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][4])
                if (countToRightIndex == randomOnePerfectMoveOfThisPerfectFigure)
                {
                    randomOnePerfectMoveOfThisPerfectFigure = crossMovesOfCurrentFigure;
                    break;
                }
                else
                    countToRightIndex++;

        #endregion
    }

    private static void AddAllCandidates() // Зарежда всички кандидати за избор на следващия максимално добър компютърен ход 
    {
        candidates.Clear();
        for (aiaacf = 0; aiaacf < possibleMoves[playerToMove].Count; aiaacf++)
        {
            candidates.Add(new List<int>());
            candidates[aiaacf].Add(possibleMoves[playerToMove][aiaacf].Count - 1);
            for (aiaacm = 1; aiaacm < possibleMoves[playerToMove][aiaacf].Count; aiaacm++)
                candidates[aiaacf].Add(1);
        }
    }

    public static bool AvoidMateInOne() // Проверява дали след избран ход, опонента има възможност за мат в един ход 
    {
        //erori = "before";     MyError();

        lastTakes = false; // вместо takes = false, тъй като по-късно ще стане припокриване
        lastExchangeDifference = 0; // вместо exchange = false, тъй като по-късно ще стане припокриване, а сега я ползвам двуяко

        #region Правим виртуалния ход

            #region Рокада и Ан Пасан

        if (16 < possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
        {
            enPassantPreparing = -8; //! (-9 <) -8 < 0 Ако е проверява какво става след евентуална рокада или ан пасан, след това oppositePlayer няма да може да направи ан пасан!

            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] < 19)
            {
                king = figures[playerToMove][0][0];
                if (playerToMove == 0)
                    castleRow = 0;
                else
                    castleRow = 7;

                if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] == 17)
                {
                    figures[playerToMove][2][0] = 6;
                    MakeMove(0, castleRow, 4, king, castleRow, 6);
                    indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 7);
                    figures[playerToMove][2][indexOfCastleRook] = 5;
                    MakeMove(0, castleRow, 7, king - kingUnits + rookUnits, castleRow, 5);
                }
                else // == 18
                {
                    figures[playerToMove][2][0] = 2;
                    MakeMove(0, castleRow, 4, king, castleRow, 2);
                    indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 0);
                    figures[playerToMove][2][indexOfCastleRook] = 3;
                    MakeMove(0, castleRow, 0, king - kingUnits + rookUnits, castleRow, 3);
                }
            }
            else // 18 < ...
            {
                if (playerToMove == 0)
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3]);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
                else
                {
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3]);
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] - 1;
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];

                    savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                    MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] - 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    MakeMove(emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
            }
        }

            #endregion

            #region Обикновен ход

        else
        {
            lastSavePositions[playerToMove][0][0] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1];
            lastSavePositions[playerToMove][0][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
            lastSavePositions[playerToMove][0][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];
            lastSavePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, lastSavePositions[playerToMove][0][1], lastSavePositions[playerToMove][0][2]);

            lastSavePositions[playerToMove][1][0] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1];
            lastSavePositions[playerToMove][1][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            lastSavePositions[playerToMove][1][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];

            if ((lastSavePositions[playerToMove][0][0] == figures[playerToMove][0][0] - kingUnits + pawnUnits) 
                && ((lastSavePositions[playerToMove][0][1] - lastSavePositions[playerToMove][1][1] == -2)
                       || (lastSavePositions[playerToMove][0][1] - lastSavePositions[playerToMove][1][1] == 2)))
                enPassantPreparing = lastSavePositions[playerToMove][0][2];
            else
                enPassantPreparing = -8;

            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1] != 0)
            {
                lastTakes = true;
                lastSavePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, lastSavePositions[playerToMove][1][1], lastSavePositions[playerToMove][1][2]);
                materials[oppositePlayer] -= figures[oppositePlayer][0][lastSavePositions[playerToMove][1][3]]; // lastSavePositions[playerToMove][1][0];
                RemoveFigureAtPosition(oppositePlayer, lastSavePositions[playerToMove][1][3]);
            }

            figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            figures[playerToMove][2][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];
            MakeMove(0, possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
            if ((figures[playerToMove][0][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                && (((playerToMove == 0) && (figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == 7))
                    || ((playerToMove == 1) && (figures[playerToMove][1][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] == 0))))
            {
                exchange = true;
                switch (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][5])
                {
                    case 0: { exchangeWith = figures[playerToMove][0][0] - kingUnits + queenUnits; break; }
                    case 1: { exchangeWith = figures[playerToMove][0][0] - kingUnits + nightUnits; break; }
                    default: break;
                }

                battlefield[possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]] = exchangeWith;
                figures[playerToMove][0][possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][0]] = exchangeWith;
                materials[playerToMove] += exchangeWith - (figures[playerToMove][0][0] - kingUnits) - pawnUnits;

                lastExchangeDifference = exchangeWith - (figures[playerToMove][0][0] - kingUnits) - pawnUnits;
            }
        }

            #endregion

            //! Не е необходимо да запазваме виртуално масата и ... , тъй като ще търсим само мат в един ход, не и пат!

        #endregion

        ChangePlayerToMove();

        FindAllPossibleMoves();

        #region Проверяваме САМО ЗА МАТ в един ход

        maxGoodMoveOfAllFigures = 0;

        for (aicfmioi = 0; aicfmioi < possibleMoves[playerToMove].Count; aicfmioi++)
        {
            for (aicfmioj = 1; aicfmioj < possibleMoves[playerToMove][aicfmioi].Count; aicfmioj++)
            {
                maxGoodMoveOfAllFigures = 0; // търсим дали има SAMO MAT

                takes = false;
                exchange = false;

                possibleMoves[playerToMove][aicfmioi][aicfmioj].Add(0); // създаваме [4] = 0 на РЕАЛНО oppositePlayer

                #region Рокада и Ан Пасан

                if (16 < possibleMoves[playerToMove][aicfmioi][aicfmioj][0])
                {
                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19)
                    {
                        king = figures[playerToMove][0][0];
                        if (playerToMove == 0)
                            castleRow = 0;
                        else
                            castleRow = 7;

                        if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] == 17)
                        {
                            figures[playerToMove][2][0] = 6;
                            MakeMove(0, castleRow, 4, king, castleRow, 6);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 7);
                            if (indexOfCastleRook == -1)
                                FullPrint();

                            figures[playerToMove][2][indexOfCastleRook] = 5; // Грешка! : indexOfCastleRook = -1 // въпреки че малка рокада е невъзможна // Поправена чрез зануляване на castle = Castle.noCastle преди всеки следващ реален ход в енджина!!!
                            MakeMove(0, castleRow, 7, king - kingUnits + rookUnits, castleRow, 5);
                        }
                        else // == 18
                        {
                            figures[playerToMove][2][0] = 2;
                            MakeMove(0, castleRow, 4, king, castleRow, 2);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 0);
                            if (indexOfCastleRook == -1)
                                FullPrint();

                            figures[playerToMove][2][indexOfCastleRook] = 3; // Грешка! : indexOfCastleRook = -1 // въпреки че малка рокада е невъзможна // Поправена чрез зануляване на castle = Castle.noCastle преди всеки следващ реален ход в енджина!!!
                            MakeMove(0, castleRow, 0, king - kingUnits + rookUnits, castleRow, 3);
                        }

                        savePositions[playerToMove][0][0] = figures[playerToMove][0][0]; // само за ориентир за по следващата проверка, че е играна рокада, който е ход за ++repetitionDraw и ++Fifty-rule
                    }
                    else // 18 < ...
                    {
                        //takes = true; // не ни трябва

                        if (playerToMove == 0)
                        {
                            savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3]);
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1;
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                            savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                        else
                        {
                            savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3]);
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1;
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                            savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);

                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], figures[playerToMove][0][0] - kingUnits + pawnUnits, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                    }
                }

                #endregion

                #region Обикновен ход

                    #region Евентуално влиза царица

                else
                {
                    savePositions[playerToMove][0][0] = possibleMoves[playerToMove][aicfmioi][0][1];
                    savePositions[playerToMove][0][1] = possibleMoves[playerToMove][aicfmioi][0][2];
                    savePositions[playerToMove][0][2] = possibleMoves[playerToMove][aicfmioi][0][3];
                    savePositions[playerToMove][0][3] = ReturnIndexOfFigure(playerToMove, savePositions[playerToMove][0][1], savePositions[playerToMove][0][2]);

                    savePositions[playerToMove][1][0] = possibleMoves[playerToMove][aicfmioi][aicfmioj][1];
                    savePositions[playerToMove][1][1] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2];
                    savePositions[playerToMove][1][2] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];

                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][1] != 0)
                    {
                        takes = true;
                        savePositions[playerToMove][1][3] = ReturnIndexOfFigure(oppositePlayer, savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                        // Error!   index = -1   Поправена!
                        materials[oppositePlayer] -= figures[oppositePlayer][0][savePositions[playerToMove][1][3]]; // savePositions[playerToMove][1][0];
                        RemoveFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3]);
                    }

                    figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][2];
                    figures[playerToMove][2][possibleMoves[playerToMove][aicfmioi][0][0]] = possibleMoves[playerToMove][aicfmioi][aicfmioj][3];
                    MakeMove(0, possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                    if ((figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] == figures[playerToMove][0][0] - kingUnits + pawnUnits)
                        && (((playerToMove == 0) && (figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] == 7))
                            || ((playerToMove == 1) && (figures[playerToMove][1][possibleMoves[playerToMove][aicfmioi][0][0]] == 0))))
                    {
                        exchange = true;
                        exchangeWith = figures[playerToMove][0][0] - kingUnits + queenUnits;
                        battlefield[possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]] = exchangeWith;
                        figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] = exchangeWith;
                        materials[playerToMove] += queenUnits - pawnUnits;

                        possibleMoves[playerToMove][aicfmioi][aicfmioj].Add(0); // създаваме [5] = 0 == Queen
                    }
                }

                    #endregion

                    #region Обикновена проверка за анонса СЛЕД хода

                if (Checks(oppositePlayer))
                    if (!OppositeAvoid())
                        maxGoodMoveOfAllFigures = 3;

                //if (false)
                //{
                //    if (Checks(oppositePlayer))
                //    {
                //        if (OppositeAvoid())
                //            possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 1;
                //        else
                //            possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 3;
                //    }
                //    else
                //    {
                //        if (OppositeAvoid())
                //            possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 0;
                //        else
                //            possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                //    }
                //}

                    #endregion

                    #region Проверка за Repetition, Material и Fifty СЛЕД хода

                //if (false)
                //{
                    //if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19)
                    //{
                    //    if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук ползвам ориентира
                    //    {
                    //        // ПЪРВО трябва по-нагоре, веднага след изиграване на виртуалния ход, да проверя SaveBattlefield[], maxMatches  и променливите ...

                    //        //if (takes)
                    //        if (((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                    //                && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop))
                    //                || (50 <= passiveMoves[oppositePlayer])) // всъщност това е на истинския playerToMove (в момента са разменени)
                    //            // В такъв случай липсва проверката за възможни =RMF още преди самия ход на опонента !!!
                    //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                    //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2; // Material и Fifty(на истинския playerToMove) ???
                    //    }
                    //    else
                    //    {
                    //        saveCurrentBattlefield.Clear();
                    //        for (aicfmioscbi = 0; aicfmioscbi <= 7; aicfmioscbi++)
                    //            for (aicfmioscbj = 0; aicfmioscbj <= 7; aicfmioscbj++)
                    //                saveCurrentBattlefield.Append(battlefield[aicfmioscbi, aicfmioscbj]);

                    //        currentBattlefield = saveCurrentBattlefield.ToString();
                    //        maxRepetitionWithCurrentBattlefield = 1; // беше 0
                    //        for (aicfmioscbk = 0; aicfmioscbk < saveBattlefields.Count; aicfmioscbk++)
                    //            if (saveBattlefields[aicfmioscbk] == currentBattlefield)
                    //                maxRepetitionWithCurrentBattlefield++;

                    //        if ((3 <= maxRepetitionWithCurrentBattlefield)
                    //                || (49 <= passiveMoves[playerToMove])) // беше 50
                    //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                    //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                    //    }
                    //}
                //}

                    #endregion

                    #region Евентуално влиза кон

                    if (exchange)
                    {
                        exchangeWith = figures[playerToMove][0][0] - kingUnits + nightUnits;
                        battlefield[possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]] = exchangeWith;
                        figures[playerToMove][0][possibleMoves[playerToMove][aicfmioi][0][0]] = exchangeWith;
                        materials[playerToMove] -= queenUnits - nightUnits;

                        #region Надграждаща обикновена проверка за анонса СЛЕД хода

                        if (maxGoodMoveOfAllFigures < 3)
                            if (Checks(oppositePlayer))
                                if (!OppositeAvoid())
                                    maxGoodMoveOfAllFigures = 3;

                        //if (false)
                        //{
                        //    if (Checks(oppositePlayer))
                        //    {
                        //        if (OppositeAvoid())
                        //        {
                        //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 1)
                        //            {
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 1;
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                        //            }
                        //        }
                        //        else
                        //        {
                        //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 3)
                        //            {
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 3;
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                        //            }
                        //        }
                        //    }
                        //    else
                        //    {
                        //        if (OppositeAvoid())
                        //        {
                        //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 0)
                        //            {
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 0;
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                        //            }
                        //        }
                        //        else
                        //        {
                        //            if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                        //            {
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                        //                possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                        //            }
                        //        }
                        //    }
                        //}

                        #endregion

                        #region Проверка за Material и Fifty СЛЕД хода

                        //if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19) // излишна проверка, тъй като, ако не е обикновен ход, exchange == false
                        //{
                            ////if ((savePositions[playerToMove][0][0] % 10 == pawnUnits) || takes) // тук също ползвам ориентира
                            ////{
                            ////    if (takes)
                            //if (false)
                            //{
                            //    if (((materials[0] == whiteKing) || (materials[0] == whiteKingPlusNight) || (materials[0] == whiteKingPlusBishop))
                            //            && ((materials[1] == blackKing) || (materials[1] == blackKingPlusNight) || (materials[1] == blackKingPlusBishop))
                            //            || (50 <= passiveMoves[oppositePlayer])) // на истинския playerToMove
                            //        if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                            //        {
                            //            possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                            //            possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            //        }
                            //}
                            ////}
                            ////else
                            ////{
                            ////saveCurrentBattlefield.Clear();
                            ////for (aicfmioscbi = 0; aicfmioscbi <= 7; aicfmioscbi++)
                            ////    for (aicfmioscbj = 0; aicfmioscbj <= 7; aicfmioscbj++)
                            ////        saveCurrentBattlefield.Append(battlefield[aicfmioscbi, aicfmioscbj]);

                            ////currentBattlefield = saveCurrentBattlefield.ToString();
                            ////maxRepetitionWithCurrentBattlefield = 0;
                            ////for (aicfmioscbk = 0; aicfmioscbk < saveBattlefields.Count; aicfmioscbk++)
                            ////    if (saveBattlefields[aicfmioscbk] == currentBattlefield)
                            ////        maxRepetitionWithCurrentBattlefield++;

                            ////if ((3 <= maxRepetitionWithCurrentBattlefield)
                            ////        || (50 <= passiveMoves[playerToMove]))
                            ////    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] < 2)
                            ////    {
                            ////        possibleMoves[playerToMove][aicfmioi][aicfmioj][4] = 2;
                            ////        possibleMoves[playerToMove][aicfmioi][aicfmioj][5] = 1;
                            ////    }
                            ////}
                        //}

                        #endregion
                    }

                    #endregion

                #endregion

                #region Връщаме евентуалния ход (на opposite) назад

                    #region Рокада или Ан Пасан

                if (16 < possibleMoves[playerToMove][aicfmioi][aicfmioj][0])
                {
                    if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] < 19)
                    {
                        king = figures[playerToMove][0][0];
                        if (playerToMove == 0)
                            castleRow = 0;
                        else
                            castleRow = 7;

                        if (possibleMoves[playerToMove][aicfmioi][aicfmioj][0] == 17)
                        {
                            figures[playerToMove][2][0] = 4;
                            MakeMove(king, castleRow, 4, 0, castleRow, 6);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 5);
                            figures[playerToMove][2][indexOfCastleRook] = 7;
                            MakeMove(king - kingUnits + rookUnits, castleRow, 7, 0, castleRow, 5);
                        }
                        else
                        {
                            figures[playerToMove][2][0] = 4;
                            MakeMove(king, castleRow, 4, 0, castleRow, 2);
                            indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 3);
                            figures[playerToMove][2][indexOfCastleRook] = 0;
                            MakeMove(king - kingUnits + rookUnits, castleRow, 0, 0, castleRow, 3);
                        }
                    }
                    else
                    {
                        if (playerToMove == 0)
                        {
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][2];
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][3];

                            AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);

                            MakeMove(possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] + 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                        else
                        {
                            figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][2];
                            figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][aicfmioi][0][3];

                            AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);

                            MakeMove(possibleMoves[playerToMove][aicfmioi][0][1], possibleMoves[playerToMove][aicfmioi][0][2], possibleMoves[playerToMove][aicfmioi][0][3], emptyField, possibleMoves[playerToMove][aicfmioi][aicfmioj][2] - 1, possibleMoves[playerToMove][aicfmioi][aicfmioj][3]);
                            MakeMove(possibleMoves[playerToMove][aicfmioi][aicfmioj][1], possibleMoves[playerToMove][aicfmioi][aicfmioj][2], possibleMoves[playerToMove][aicfmioi][aicfmioj][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                        }
                    }
                }

                    #endregion

                    #region Обикновен ход

                else
                {
                    figures[playerToMove][0][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][0];
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][1];
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = savePositions[playerToMove][0][2];
                    MakeMove(savePositions[playerToMove][0][0], savePositions[playerToMove][0][1], savePositions[playerToMove][0][2], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                    if (takes)
                    {
                        AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], savePositions[playerToMove][1][0], savePositions[playerToMove][1][1], savePositions[playerToMove][1][2]);
                        materials[oppositePlayer] += figures[oppositePlayer][0][savePositions[playerToMove][1][3]];
                    }

                    if (exchange)
                        materials[playerToMove] -= nightUnits - pawnUnits;
                }

                    #endregion

                #endregion

                #region Спираме търсенето измежду ходовете на тази фигура при първия намерен мат в един ход

                if (maxGoodMoveOfAllFigures == 3)
                    break;

                //if (possibleMoves[playerToMove][aicfmioi][aicfmioj][4] == 3)
                //{
                //    maxGoodMoveOfAllFigures = 3;
                //    break;
                //}

                #endregion
            }

            #region Спираме търсенето измежду ходовете на всички фигури при първия намерен мат в един ход

            if (maxGoodMoveOfAllFigures == 3)
                break;

            #endregion

            #region Намираме първия най-добър ход на разглежданата фигура

            //if (false)
            //{
            //    maxGoodMoveOfCurrentFigure = possibleMoves[playerToMove][aicfmioi][1][4];
            //    maxGoodMoveOfCurrentFigureIndex = 1;
            //    for (crossMovesOfCurrentFigure = 2; crossMovesOfCurrentFigure < possibleMoves[playerToMove][aicfmioi].Count; crossMovesOfCurrentFigure++)
            //        if (maxGoodMoveOfCurrentFigure < possibleMoves[playerToMove][aicfmioi][crossMovesOfCurrentFigure][4])
            //        {
            //            maxGoodMoveOfCurrentFigure = possibleMoves[playerToMove][aicfmioi][crossMovesOfCurrentFigure][4];
            //            maxGoodMoveOfCurrentFigureIndex = crossMovesOfCurrentFigure;
            //        }

            //    possibleMoves[playerToMove][aicfmioi][0].Add(maxGoodMoveOfCurrentFigure);
            //    possibleMoves[playerToMove][aicfmioi][0].Add(maxGoodMoveOfCurrentFigureIndex);
            //}

            #endregion

            #region 'Накрая' намираме първата перфектна фигура

            //if (false)
            //{
            //    if (maxGoodMoveOfAllFigures < maxGoodMoveOfCurrentFigure)
            //        maxGoodMoveOfAllFigures = maxGoodMoveOfCurrentFigure;
            //}

            #endregion
        }

        #endregion

        //erori = "middle";

        ChangePlayerToMove();

        #region Връщаме виртуалния ход назад

            #region Рокада и Ан Пасан

        if (16 < possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
        {
            if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] < 19)
            {
                king = figures[playerToMove][0][0];
                if (playerToMove == 0)
                    castleRow = 0;
                else
                    castleRow = 7;

                if (possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0] == 17)
                {
                    figures[playerToMove][2][0] = 4;
                    MakeMove(king, castleRow, 4, 0, castleRow, 6);
                    indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 5);
                    figures[playerToMove][2][indexOfCastleRook] = 7;
                    MakeMove(king - kingUnits + rookUnits, castleRow, 7, 0, castleRow, 5);
                }
                else
                {
                    figures[playerToMove][2][0] = 4;
                    MakeMove(king, castleRow, 4, 0, castleRow, 2);
                    indexOfCastleRook = ReturnIndexOfFigure(playerToMove, castleRow, 3);
                    figures[playerToMove][2][indexOfCastleRook] = 0;
                    MakeMove(king - kingUnits + rookUnits, castleRow, 0, 0, castleRow, 3);
                }
            }
            else
            {
                if (playerToMove == 0)
                {
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);

                    MakeMove(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    MakeMove(possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
                else
                {
                    figures[playerToMove][1][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
                    figures[playerToMove][2][savePositions[playerToMove][0][3]] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];

                    AddFigureAtPosition(oppositePlayer, savePositions[playerToMove][1][3], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);

                    MakeMove(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3], emptyField, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] - 1, possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3]);
                    MakeMove(possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][1], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2], possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3], figures[playerToMove][0][0], figures[playerToMove][1][0], figures[playerToMove][2][0]); // царя на playerToMove подскача на едно място
                }
            }
        }

            #endregion

            #region Обикновен ход

        else
        {
            figures[playerToMove][0][lastSavePositions[playerToMove][0][3]] = lastSavePositions[playerToMove][0][0];
            figures[playerToMove][1][lastSavePositions[playerToMove][0][3]] = lastSavePositions[playerToMove][0][1];
            figures[playerToMove][2][lastSavePositions[playerToMove][0][3]] = lastSavePositions[playerToMove][0][2];
            MakeMove(lastSavePositions[playerToMove][0][0], lastSavePositions[playerToMove][0][1], lastSavePositions[playerToMove][0][2], lastSavePositions[playerToMove][1][0], lastSavePositions[playerToMove][1][1], lastSavePositions[playerToMove][1][2]);
            if (lastTakes)
            {
                AddFigureAtPosition(oppositePlayer, lastSavePositions[playerToMove][1][3], lastSavePositions[playerToMove][1][0], lastSavePositions[playerToMove][1][1], lastSavePositions[playerToMove][1][2]);
                materials[oppositePlayer] += figures[oppositePlayer][0][lastSavePositions[playerToMove][1][3]];
            }

            materials[playerToMove] -= lastExchangeDifference; // тъй като във всеки случай имамехме 'локален exchange'
        }

            #endregion

        #endregion

        //MyError();        erori = "after";        MyError();

        #region Генерално различие

        if (maxGoodMoveOfAllFigures == 3)
            return false;
        else
            return true;

        #endregion
    }

    private static void MyError() // Проверява за грешки от сорта на бяла фигура заменя черна пешка 
    {
        for (me = 0; me < figures[0][0].Count; me++)
        {
            if ((figures[0][0][me] < 11) || (16 < figures[0][0][me]))
            {
                FullPrint();
                Console.ReadKey();
            }
        }

        for (me = 0; me < figures[1][0].Count; me++)
        {
            if ((figures[1][0][me] < 31) || (36 < figures[1][0][me]))
            {
                FullPrint();
                Console.ReadKey();
            }
        }
    }

    public static void BuildTextOfMove() // Създава почти целия компютърен ход в писмен вид, с изключение в случай на СПЕЦИАЛЕН пат 
    {
        buildTextOfMove.Clear();
        if (17 == possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
            buildTextOfMove.Append(castleKingsideFree);
        else if (18 == possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][0])
            buildTextOfMove.Append(castleQueensideFree);
        else
        {
            buildTextOfMove.Append(FigureSign(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1]));
            if (computerNotationCurrent == Notation.LongAlgebraic)
            {
                buildTextOfMove.Append((char)(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3] + 97));
                buildTextOfMove.Append((possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2] + 1));
                if (takes)
                {
                    if (enPassant)
                        buildTextOfMove.Append(enPassantSymbol);
                    else
                        buildTextOfMove.Append(takeSymbol);
                }
                else
                    buildTextOfMove.Append(moveSymbol);
            }
            else if (computerNotationCurrent == Notation.ShortAlgebraic)
            {
                if (savePositions[playerToMove][0][0] % 10 != kingUnits)
                {
                    if (savePositions[playerToMove][0][0] % 10 == pawnUnits)
                    {
                        if (takes)
                            buildTextOfMove.Append((char)(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3] + 97));
                    }
                    else
                    {
                        if (shortAlgebraicHowManyFiguresCanJump != 0)
                        {
                            if (shortAlgebraicHowManyFiguresCanJump == 1)
                                buildTextOfMove.Append((char)(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3] + 97));
                            else if (shortAlgebraicHowManyFiguresCanJump == 2)
                                buildTextOfMove.Append((possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2] + 1));
                            else
                            {
                                buildTextOfMove.Append((char)(possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3] + 97));
                                buildTextOfMove.Append((possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2] + 1));
                            }
                        }
                    }
                }

                if (takes)
                {
                    if (enPassant)
                        buildTextOfMove.Append(enPassantSymbol);
                    else
                        buildTextOfMove.Append(takeSymbol);
                }
            }

            buildTextOfMove.Append((char)(possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3] + 97));
            if (enPassant)
                buildTextOfMove.Append((possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1 + (playerToMove == 0 ? 1 : -1)));
            else
                buildTextOfMove.Append((possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2] + 1));

            if (exchange)
                buildTextOfMove.Append(exchangeSymbol + FigureSign(exchangeWith));

            //savePositions[playerToMove][0][0] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][1];
            //savePositions[playerToMove][0][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][2];
            //savePositions[playerToMove][0][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][0][3];
            //savePositions[playerToMove][1][1] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][2];
            //savePositions[playerToMove][1][2] = possibleMoves[playerToMove][randomIndexOfPerfectFigure][randomOnePerfectMoveOfThisPerfectFigure][3];
        }

        if (give == States.Check)
            buildTextOfMove.Append(checkSymbol);
        else if (give == States.Checkmate)
            buildTextOfMove.Append(checkmateSymbol);
        else if (give == States.Draw)
        {
            if (Checks(oppositePlayer))
            {
                buildTextOfMove.Append(checkSymbol);

                if (castled) //! САМО при Fifty (истинския oppositePlayer), ако oppositePlayer е проиграл възможността
                {
                    if (castle == Castles.castleKingsideDraw)
                        castle = Castles.castleKingsideCheckAndDraw;
                    else
                        castle = Castles.castleQueensideCheckAndDraw;
                }
            }

            buildTextOfMove.Append(drawSymbol);
        }
    }

    public static string FigureSign(int figure) // Връща знак на фигура
    {
        switch (figure % 10)
        {
            case kingUnits:     return "K";
            case queenUnits:    return "Q";
            case rookUnits:     return "R";
            case bishopUnits:   return "B";
            case nightUnits:    return "N";
            case pawnUnits:     return "";
            default:            return "";
        }
    }

    #endregion

    #region Figures players' / Фигури на играчите

    public static void RemoveFigureAtPosition(int player, int index) // Премахва от колода фигура под определен индекс
    {
        figures[player][0].RemoveAt(index);
        figures[player][1].RemoveAt(index);
        figures[player][2].RemoveAt(index);
    }

    public static void AddFigureAtPosition(int player, int index, int figure, int row, int column) // Добавя фигура на определена позиция в колодата 
    {
        figures[player][0].Insert(index, figure);
        figures[player][1].Insert(index, row);
        figures[player][2].Insert(index, column);
    }

    public static void FiguresRearrangement(int reduceThisIndex) // Подрежда колодата на ТЕКУЩИЯ** играч в низходящ ред по стойност (последна от вида е новоизлязлата) 
    {
        fpri = reduceThisIndex - 1;
        while (figures[playerToMove][0][fpri] < figures[playerToMove][0][reduceThisIndex])
            fpri--;

        fpri++;
        if (fpri < reduceThisIndex)
        {
            fprv = figures[playerToMove][0][reduceThisIndex];
            figures[playerToMove][0].RemoveAt(reduceThisIndex);
            figures[playerToMove][0].Insert(fpri, fprv);

            fprv = figures[playerToMove][1][reduceThisIndex];
            figures[playerToMove][1].RemoveAt(reduceThisIndex);
            figures[playerToMove][1].Insert(fpri, fprv);

            fprv = figures[playerToMove][2][reduceThisIndex];
            figures[playerToMove][2].RemoveAt(reduceThisIndex);
            figures[playerToMove][2].Insert(fpri, fprv);

            //FullPrint(); // само за тестове
        }
    }

    #endregion

    #region Change player to move / Смяна на играча

    public static void ChangePlayerToMove() // Сменя ТЕКУЩИЯ играч, който да е на (може и виртуален) ход 
    {
        oppositePlayer = playerToMove;
        playerToMove = 1 - playerToMove;
    }

    #endregion
}